Commit cc54439f authored by 周文华's avatar 周文华

【新增】新增迁移病毒扫描功能(有些待兼容调整)

parent eb5910dd
...@@ -66,7 +66,15 @@ gradle.taskGraph.whenReady { ...@@ -66,7 +66,15 @@ gradle.taskGraph.whenReady {
} }
dependencies { dependencies {
implementation(
fileTree(
mapOf(
"dir" to "libs",
"include" to listOf("*.aar", "*.jar"),
"exclude" to emptyList<String>()
)
)
)
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat) implementation(libs.androidx.appcompat)
implementation(libs.material) implementation(libs.material)
......
...@@ -18,4 +18,9 @@ ...@@ -18,4 +18,9 @@
# If you keep the line number information, uncomment this to # If you keep the line number information, uncomment this to
# hide the original source file name. # hide the original source file name.
#-renamesourcefileattribute SourceFile #-renamesourcefileattribute SourceFile
\ No newline at end of file
#病毒扫描
-keep class com.trustlook.** {
*;
}
\ No newline at end of file
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" /> <!-- 三星和 LG 厂商通知角标权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" /> <!-- 三星和 LG 厂商通知角标权限 -->
<uses-permission android:name="com.sec.android.provider.badge.permission.READ" /> <uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" /> <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<queries> <queries>
<intent> <intent>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
...@@ -37,6 +37,10 @@ ...@@ -37,6 +37,10 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.SwiftCleanerPhoneHelper" android:theme="@style/Theme.SwiftCleanerPhoneHelper"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".view.activity.MalwareCleanActivity"
android:exported="false"
android:launchMode="singleTop" />
<activity <activity
android:name=".view.function.weather.WeatherInterface" android:name=".view.function.weather.WeatherInterface"
android:exported="false" /> android:exported="false" />
...@@ -200,6 +204,10 @@ ...@@ -200,6 +204,10 @@
<meta-data <meta-data
android:name="com.facebook.sdk.ApplicationId" android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" /> android:value="@string/facebook_app_id" />
<meta-data
android:value="cedfde13feb689ade7154c6322525c2d9fc10397fac1d4da5580542e"
android:name="com.trustlook.ApiKey" />
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package com.swiftcleaner.chovey.model.bean; package com.swiftcleaner.chovey.model.bean;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
...@@ -8,12 +9,28 @@ public class AppInfoBean { ...@@ -8,12 +9,28 @@ public class AppInfoBean {
private Drawable appIcon; private Drawable appIcon;
private String packageName; private String packageName;
public Boolean isSelected = false;
public Boolean isInstall = null;
public Integer score = null;
public String apkPath = null;
public AppInfoBean(String appName, Drawable appIcon, String packageName) { public AppInfoBean(String appName, Drawable appIcon, String packageName) {
this.appName = appName; this.appName = appName;
this.appIcon = appIcon; this.appIcon = appIcon;
this.packageName = packageName; this.packageName = packageName;
} }
public AppInfoBean(String appName, Drawable appIcon, String packageName, Boolean isSelected, Boolean isInstall, Integer score, String apkPath) {
this.appName = appName;
this.appIcon = appIcon;
this.packageName = packageName;
this.isSelected = isSelected;
this.isInstall = isInstall;
this.score = score;
this.apkPath = apkPath;
}
// Getters and setters // Getters and setters
public String getAppName() { public String getAppName() {
return appName; return appName;
......
package com.swiftcleaner.chovey.util
import com.swiftcleaner.chovey.CleanApplication
import com.trustlook.sdk.cloudscan.CloudScanClient
import com.trustlook.sdk.data.Region
/**
*Create by SleepDog on 2025-01-24
*/
object CloudScan {
val scanClient by lazy(LazyThreadSafetyMode.NONE) {
CloudScanClient.Builder(CleanApplication.context)
// 设置服务地区,
// 海外地区设置:Region.INTL,百度用户设置:Region.BAIDU
.setRegion(Region.INTL)
// 设置连接超时时长,单位为毫秒
.setConnectionTimeout(30000)
//设置传输超时时长,单位为毫秒
.setSocketTimeout(30000)
.build()
}
}
\ No newline at end of file
package com.swiftcleaner.chovey.view.activity
import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.addCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.gms.ads.nativead.NativeAd
import com.gyf.immersionbar.ImmersionBar
import com.swiftcleaner.chovey.R
import com.swiftcleaner.chovey.business.admob.AdmobManager.isShowAdBackInter
import com.swiftcleaner.chovey.business.admob.AdmobManager.isShowAdInter
import com.swiftcleaner.chovey.business.admob.AdmobManager.showInterstitialAd
import com.swiftcleaner.chovey.business.admob.AdmobManager.showNativeAd
import com.swiftcleaner.chovey.databinding.ActivityMalwareCleanBinding
import com.swiftcleaner.chovey.databinding.DialogErrBinding
import com.swiftcleaner.chovey.databinding.ItemMalwareCleanBinding
import com.swiftcleaner.chovey.model.bean.AppInfoBean
import com.swiftcleaner.chovey.model.tool.FileHelps
import com.swiftcleaner.chovey.model.util.FinishMain.finishToMain
import com.swiftcleaner.chovey.util.ActivityLauncher
import com.swiftcleaner.chovey.util.CloudScan
import com.swiftcleaner.chovey.view.dialog.CustomScoreDialog
import com.trustlook.sdk.cloudscan.CloudScanListener
import com.trustlook.sdk.data.AppInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.random.Random
class MalwareCleanActivity : AppCompatActivity() {
private val binding by lazy(LazyThreadSafetyMode.NONE) {
ActivityMalwareCleanBinding.inflate(layoutInflater)
}
private var appList = mutableListOf<AppInfoBean>()
private val adapter by lazy(LazyThreadSafetyMode.NONE) {
class ViewHolder(val binding: ItemMalwareCleanBinding) :
RecyclerView.ViewHolder(binding.root)
object : RecyclerView.Adapter<ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemMalwareCleanBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return ViewHolder(binding)
}
override fun getItemCount(): Int = appList.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = appList[position]
holder.binding.ivIcon.setImageDrawable(item.appIcon)
holder.binding.tvName.text = item.appName
holder.binding.tvLevel.text = getLevel(item.score ?: 0)
holder.binding.viewLine.visibility =
if (position == itemCount - 1) View.GONE else View.VISIBLE
holder.itemView.setOnClickListener {
item.isSelected = !item.isSelected
if (isShowAdInter()) {
showInterstitialAd(this@MalwareCleanActivity, dismissed = {
uninstall(0, listOf(item))
}, failed = {
uninstall(0, listOf(item))
}, isRetry = false)
}
}
}
}
}
private fun getLevel(score: Int): String {
return if (score <= 5) {
"safe"
} else if (score in 6..7) {
"Risk"
} else {
"malware"
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initBar()
setContentView(binding.root)
initView()
onBackPressedDispatcher.addCallback {
initCustomDialog()
}
}
override fun onResume() {
super.onResume()
initData()
}
private fun initView() {
binding.clRadarview.isVisible = true
binding.radarview.setSearching(true)
showNativeAd(this, { nativeAd: NativeAd? ->
nativeAd?.let {
binding.flAdDonghua.removeAllViews()
binding.flAdDonghua.setNativeAd(nativeAd, R.layout.layout_ad_native)
}
}, null, null)
if (isShowAdInter()) {
showInterstitialAd(this@MalwareCleanActivity, dismissed = {
initData(false)
}, failed = {
initData(false)
}, isRetry = false)
}
binding.rvMalware.adapter = adapter
binding.rvMalware.layoutManager = LinearLayoutManager(this)
binding.flBack.setOnClickListener { onBackPressedDispatcher.onBackPressed() }
binding.tvDelete.setOnClickListener {
val list = appList.filter { it.isSelected }
if (list.isNotEmpty()) {
binding.tvDelete.isEnabled = false
malwareClean(list)
}
}
}
private var isScanning = true
private fun scanFinish() {
isScanning = false
binding.clRadarview.isVisible = false
binding.radarview.setSearching(false)
}
private fun initData(isScan: Boolean = isScanning) {
if (isScan) return
isScanning = true
CloudScan.scanClient.startQuickScan(object : CloudScanListener() {
override fun onScanStarted() {
// Log.e("CloudScan","onScanStarted")
}
override fun onScanCanceled() {
scanFinish()
// Log.e("CloudScan","onScanCanceled")
}
override fun onScanProgress(current: Int, total: Int, p2: AppInfo?) {
}
override fun onScanFinished(dataList: MutableList<AppInfo>?) {
//Log.e("CloudScan", "onScanFinished")
lifecycleScope.launch(Dispatchers.Default) {
val realList = mutableListOf<AppInfoBean>()
dataList?.forEach {
if (!it.isSystemApp
&& it.score > 5
) {
var isInstall: Boolean
// Log.e("CloudScan", "${it.source} ${it.apkPath} ${it.toJSON(this@MalwareCleanActivity)}")
val icon = try {
val res = packageManager.getApplicationIcon(it.packageName)
isInstall = true
res
} catch (e: PackageManager.NameNotFoundException) {
isInstall = false
val info = packageManager.getPackageArchiveInfo(
it.apkPath,
PackageManager.GET_ACTIVITIES
)
if (info != null) {
packageManager.getApplicationIcon(info.applicationInfo)
} else {
AppCompatResources.getDrawable(
this@MalwareCleanActivity,
R.mipmap.l_apk
)
}
}
realList.add(
AppInfoBean(
it.appName,
icon!!,
it.packageName,
false,
isInstall,
it.score,
it.apkPath
)
)
// withContext(Dispatchers.Main) {
// adapter.notifyItemInserted(appList.size)
// }
}
}
withContext(Dispatchers.Main) {
val durationTime = Random.nextLong(3000, 3500)
delay(durationTime)
appList.clear()
appList.addAll(realList)
scanFinish()
adapter.notifyDataSetChanged()
updateView()
}
}
}
override fun onScanError(p0: Int, p1: String?) {
isScanning = false
showErrDialog(this@MalwareCleanActivity) {
finishToMain(this@MalwareCleanActivity)
}
}
override fun onScanInterrupt() {
isScanning = false
showErrDialog(this@MalwareCleanActivity) {
finishToMain(this@MalwareCleanActivity)
}
}
})
}
fun showErrDialog(
context: Activity,
confirm: () -> Unit
) {
val binding = DialogErrBinding.inflate(LayoutInflater.from(context))
val dialog = Dialog(context, R.style.TransparentDialogTheme).apply {
setCancelable(false)
setCanceledOnTouchOutside(false)
setContentView(binding.root)
show()
}
binding.tvSure.setOnClickListener {
it.isEnabled = false
dialog.dismiss()
confirm.invoke()
}
showNativeAd(
context,
completed = {
binding.adNative.setExitNativeAd(it)
}
)
}
private fun updateView() {
binding.ivLogo.visibility = if (appList.isEmpty()) View.GONE else View.VISIBLE
binding.tvCount.visibility = if (appList.isEmpty()) View.GONE else {
binding.tvCount.text = "${appList.size} issue"
View.VISIBLE
}
binding.tvUnit.visibility = if (appList.isEmpty()) View.GONE else View.VISIBLE
binding.rvMalware.visibility = if (appList.isEmpty()) View.GONE else View.VISIBLE
binding.ivEmpty.visibility = if (appList.isEmpty()) View.VISIBLE else View.GONE
if (appList.isEmpty()) {
// actionCleanResult(0, getString(R.string.malware_scan))
} else {
showNativeAd(this, { nativeAd: NativeAd? ->
nativeAd?.let {
binding.adNative.removeAllViews()
binding.adNative.setNativeAd(nativeAd, R.layout.layout_ad_native)
}
}, null, null)
}
}
private fun malwareClean(list: List<AppInfoBean>) {
lifecycleScope.launch(Dispatchers.Default) {
val installApps = mutableListOf<AppInfoBean>()
list.forEach {
if (it.isInstall == true) installApps.add(it)
else {
it.apkPath?.also {
launch(Dispatchers.IO) {
FileHelps.deleteFile(it)
}
}
appList.remove(it)
}
}
if (installApps.isNotEmpty()) {
uninstall(0, installApps)
} else {
withContext(Dispatchers.Main) {
adapter.notifyDataSetChanged()
updateUninstall()
}
}
}
}
private fun uninstall(position: Int, list: List<AppInfoBean>) {
val packageName = list[position].packageName
val intent = Intent(Intent.ACTION_DELETE, Uri.parse("package:$packageName"))
ActivityLauncher(this).launch(intent) {
if (isUninstall(packageName)) {
appList.removeIf { it.packageName == packageName }
runOnUiThread {
adapter.notifyDataSetChanged()
updateUninstall()
}
}
if (position < list.size - 1) uninstall(position + 1, list)
else runOnUiThread { binding.tvDelete.isEnabled = true }
}
}
private fun isUninstall(packageName: String): Boolean {
val intent = packageManager.getLaunchIntentForPackage(packageName)
return intent == null
}
private fun updateUninstall() {
val list = appList.filter { it.isSelected }
val size = if (list.isEmpty()) "" else " ${list.size} Apps"
binding.tvDelete.text = "${getString(R.string.uninstall)}${size}"
// ResourceUtils.setTextBackground(binding.tvDelete, list.isNotEmpty())
}
private fun initCustomDialog() {
val activity: Activity = this
val customScoreDialog = CustomScoreDialog(this)
customScoreDialog.setOnDialogClickListener(object :
CustomScoreDialog.OnDialogClickListener {
override fun onCancel() {
customScoreDialog.dismiss()
}
override fun onSubmit() {
if (isShowAdBackInter()) {
showInterstitialAd(
this@MalwareCleanActivity, {
finishToMain(activity)
null
},
{ null },
{
finishToMain(activity)
null
}, false
)
} else {
finishToMain(activity)
}
}
})
customScoreDialog.show()
}
private fun initBar() {
ImmersionBar.with(this)
.transparentStatusBar() // 透明状态栏
.statusBarDarkFont(false) // 状态栏字体颜色为深色
.navigationBarDarkIcon(true) // 导航栏图标颜色为浅色
.init()
binding.clTop.updatePadding(top = ImmersionBar.getStatusBarHeight(this))
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="@color/color_181b1f"
android:endColor="@color/color_f7fafa"
android:angle="0"
android:centerX="0.5"
android:centerY="0.5" />
<corners android:radius="4dp" />
</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"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f7fafa">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_left_right_blue"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="6dp"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/fl_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:importantForAccessibility="no"
android:padding="4dp"
android:src="@mipmap/fanhui"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/malware_scan"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/fl_back"
app:layout_constraintStart_toEndOf="@id/fl_back"
app:layout_constraintTop_toTopOf="@id/fl_back" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.swiftcleaner.chovey.business.admob.NativeView
android:id="@+id/ad_native"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_top" />
<ImageView
android:id="@+id/iv_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:importantForAccessibility="no"
android:src="@mipmap/img_antivirus_scan"
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/ad_native" />
<TextView
android:id="@+id/tv_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#F8461A"
android:textSize="20sp"
android:textStyle="bold"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/tv_unit"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/tv_unit"
app:layout_constraintTop_toTopOf="@id/tv_unit"
tools:text="3 issue" />
<TextView
android:id="@+id/tv_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text=" found"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold"
android:visibility="gone"
app:layout_constraintLeft_toRightOf="@id/tv_count"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_logo" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/img_antivirus_scan_kong"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_malware"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="12dp"
android:background="@color/white"
android:paddingVertical="6dp"
android:scrollbars="none"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintTop_toBottomOf="@id/tv_unit" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp"
android:layout_marginBottom="40dp"
android:background="@drawable/shape_clean_up"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:text="@string/uninstall"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" />
<!--动画-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_radarview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_blue"
>
<com.swiftcleaner.chovey.model.tool.RadarView
android:id="@+id/radarview"
android:layout_width="262dp"
android:layout_height="262dp"
android:layout_marginTop="109dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="fitCenter"
android:src="@mipmap/dx_clean"
app:layout_constraintBottom_toBottomOf="@id/radarview"
app:layout_constraintEnd_toEndOf="@id/radarview"
app:layout_constraintStart_toStartOf="@id/radarview"
app:layout_constraintTop_toTopOf="@id/radarview" />
<ImageView
android:layout_width="match_parent"
android:layout_height="34dp"
android:scaleType="fitXY"
android:src="@mipmap/bottom_img"
app:layout_constraintBottom_toBottomOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="@string/scanning"
android:textColor="@color/white"
android:textSize="22sp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/radarview" />
<TextView
android:id="@+id/tv_recommend"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="22dp"
android:layout_marginBottom="40dp"
android:gravity="center"
android:text="@string/malware_recommended"
android:textColor="@color/white"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/tv_hint"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="@+id/tv_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:text="@string/powered_by_trustlook"
android:textColor="#CEE3FF"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@id/fl_ad_donghua"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<com.swiftcleaner.chovey.business.admob.NativeView
android:id="@+id/fl_ad_donghua"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_exit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_radio_20dp_white"
android:paddingBottom="24dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
android:includeFontPadding="false"
android:lineSpacingExtra="4dp"
android:text="Antivirus Scan error occurred,please try again"
android:textAlignment="center"
android:textColor="#1a1a1a"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_sure"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="36dp"
android:layout_marginTop="16dp"
android:background="@drawable/shape_clean_up"
android:paddingVertical="10dp"
android:text="Sure"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.swiftcleaner.chovey.business.admob.NativeView
android:id="@+id/ad_native"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@drawable/shape_radio_20dp_white"
android:padding="12dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/cl_exit" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="15dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="12dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@mipmap/logo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_weight="1"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/iv_select"
app:layout_constraintStart_toEndOf="@id/iv_icon"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/color_181b1f"
android:textSize="16sp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:background="@drawable/gradient_4"
android:backgroundTint="#FFFCF4DE"
android:paddingHorizontal="8dp"
android:paddingVertical="2dp"
android:textColor="#FFC337"
android:textSize="12sp"
tools:text="Risk" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/antivirus_delete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/view_line"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginTop="12dp"
android:background="@color/color_ebebeb"
app:layout_constraintTop_toBottomOf="@id/ll_content" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -4,4 +4,7 @@ ...@@ -4,4 +4,7 @@
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
<color name="red">#FF5722</color> <color name="red">#FF5722</color>
<color name="theme_color">#50B3FA</color> <color name="theme_color">#50B3FA</color>
<color name="color_f7fafa">#F7FAFA</color>
<color name="color_181b1f">#181B1F</color>
<color name="color_ebebeb">#EBEBEB</color>
</resources> </resources>
\ No newline at end of file
...@@ -34,4 +34,9 @@ ...@@ -34,4 +34,9 @@
<string name="fragment_gudie_three_text">Clean photos,videos,and audio files to save space and keep your phone tidy.</string> <string name="fragment_gudie_three_text">Clean photos,videos,and audio files to save space and keep your phone tidy.</string>
<string name="fragment_gudie_end_text">Maximize your storage and enjoy a clutter- free phone experience</string> <string name="fragment_gudie_end_text">Maximize your storage and enjoy a clutter- free phone experience</string>
<string name="scan_text">Attention To find junk files completely, the first scan may take a little time</string> <string name="scan_text">Attention To find junk files completely, the first scan may take a little time</string>
<string name="malware_scan">Antivirus Scan</string>
<string name="uninstall">Uninstall</string>
<string name="powered_by_trustlook">Powered by Trustlook</string>
<string name="scanning">Scanning…</string>
<string name="malware_recommended">It is recommended to turn on the network connection for more accurate results</string>
</resources> </resources>
\ 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