Commit 863297d4 authored by wanglei's avatar wanglei

...

parent f77c0718
......@@ -51,12 +51,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.permission.PermissionActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.main.MainActivity"
android:configChanges="locale"
......@@ -78,6 +73,36 @@
</intent-filter>
</activity>
<activity
android:name=".ui.weather.WeatherInterface"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.cleanjunk.ScanJunkActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.cleanjunk.CleaningActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.appprocess.AppProcessActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.permission.PermissionActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.set.SetLanguageActivity"
android:exported="false"
......
package com.base.pdfviewerscannerwhite.bean
import android.graphics.drawable.Drawable
class AppBean(
val icon: Drawable, val name: String, val packageName: String
)
\ No newline at end of file
package com.base.pdfviewerscannerwhite.bean
data class WeatherBean(val city: String, val list: List<ListBean>)
data class ListBean(
val tempMax: String,
val tempMin: String,
val humidity: String,
val fxDate: String,
val iconDay: String,
val windScaleDay: String,
val pressure: String,
val textDay: String,
val textNight: String,
)
......@@ -9,6 +9,7 @@ import com.base.pdfviewerscannerwhite.BuildConfig
import com.base.pdfviewerscannerwhite.fcm.FCMManager
import com.base.pdfviewerscannerwhite.fcm.PopupConstObject.topic_number
import com.base.pdfviewerscannerwhite.fcm.ScreenStatusReceiver
import com.base.pdfviewerscannerwhite.helper.WeatherUtils.requestWeatherData
import com.base.pdfviewerscannerwhite.ui.splash.SplashActivity
import com.base.pdfviewerscannerwhite.utils.ActivityManagerUtils
import com.base.pdfviewerscannerwhite.utils.AppPreferences
......@@ -56,6 +57,11 @@ class MyApplication : Application() {
initUUid()
initApp()
PDFBoxResourceLoader.init(applicationContext)
initWeather()
}
private fun initWeather() {
requestWeatherData()
}
private fun initUUid() {
......
package com.base.pdfviewerscannerwhite.helper
import android.text.TextUtils
import com.base.pdfviewerscannerwhite.BuildConfig
import com.base.pdfviewerscannerwhite.bean.WeatherBean
import com.base.pdfviewerscannerwhite.utils.AppPreferences
import com.base.pdfviewerscannerwhite.utils.LogEx
import com.google.gson.Gson
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.concurrent.TimeUnit
object WeatherUtils {
private val TAG = "WeatherUtils"
fun getWeatherType(param: Int): String {
val sunny_day: IntArray = intArrayOf(100, 101, 102, 103, 150, 151, 152, 153)
val cloudy_day: IntArray = intArrayOf(104)
val rainy_day: IntArray =
intArrayOf(300, 301, 302, 303, 304, 305, 306, 307, 307, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 350, 351, 399)
val snowy_day: IntArray = intArrayOf(400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 456, 457, 499)
val greasy_day: IntArray = intArrayOf(500, 501, 502, 503, 504, 505, 507, 508, 509, 510, 511, 512, 513, 514, 515)
when (param) {
in sunny_day -> return "Sunny day"
in cloudy_day -> return "Cloudy day"
in rainy_day -> return "Rainy day"
in snowy_day -> return "Snowy day"
in greasy_day -> return "Greasy day"
else -> return "Unknown"
}
}
fun hasWeatherDataToday(): Boolean {
return !TextUtils.isEmpty(getWeatherJsonStr())
}
fun getWeatherJsonStr(): String {
val data = AppPreferences.getInstance().getString(getTodayStr() + "_weather", "")
return data
}
fun getWeatherEntity(): WeatherBean? {
val str = getWeatherJsonStr()
LogEx.logDebug(TAG, "getWeatherEntity str=$str")
if (TextUtils.isEmpty(str)) {
} else {
try {
val gson = Gson()
val wBean = gson.fromJson(str, WeatherBean::class.java)
return wBean
} catch (e: Exception) {
e.printStackTrace()
}
}
return null
}
private val url by lazy {
val pkg = ConfigHelper.packageName
val url = StringBuilder(
"${ConfigHelper.apiUrl}/city/${
pkg.filter { it.isLowerCase() }.substring(4, 9)
}tq"
)
url.append("?pkg=$pkg")
val sdf = SimpleDateFormat("yyyyMMdd")
url.append("&date=${sdf.format(Calendar.getInstance().time)}")
url.toString()
}
fun requestWeatherData() {
val client = OkHttpClient.Builder().apply {
if (BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
}
}.build()
val request = Request.Builder()
.url(url)
.get()
.build()
LogEx.logDebug(TAG, "url=$url")
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
response.body?.string()?.let {
val i = Regex("\"data\":\"(.*?)\"").find(it)
if (i.toString() != "null") {
i?.groupValues?.get(1).let { data ->
LogEx.logDebug(TAG, "data=$data")
if (!TextUtils.isEmpty(data)) {
val str = AESHelper.decrypt(data ?: "")
saveWeatherData(str)
}
}
}
}
}
})
}
/**
* 同步
*/
fun getWeatherData() = runCatching {
val client = OkHttpClient.Builder().apply {
if (BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
}
}.connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(1, TimeUnit.SECONDS)
.writeTimeout(1, TimeUnit.SECONDS)
.build()
val request = Request.Builder()
.url(url)
.get()
.build()
val response = client.newCall(request).execute()
response.body?.string()?.let {
val i = Regex("\"data\":\"(.*?)\"").find(it)
if (i.toString() != "null") {
i?.groupValues?.get(1).let {
if (!TextUtils.isEmpty(it)) {
val str = AESHelper.decrypt(it!!)
saveWeatherData(str)
}
}
}
}
}
private fun saveWeatherData(string: String) {
AppPreferences.getInstance().put(getTodayStr() + "_weather", string)
}
private fun getTodayStr(): String {
val calendar = Calendar.getInstance()
val year = calendar[Calendar.YEAR]
val month = calendar[Calendar.MONTH] + 1
val day = calendar[Calendar.DAY_OF_MONTH]
val today =
year.toString() + "-" + String.format("%02d", month) + "-" + String.format("%02d", day)
return today;
}
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ui.appprocess
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.bean.AppBean
import com.base.pdfviewerscannerwhite.databinding.ItemAppProcessBinding
import com.base.pdfviewerscannerwhite.utils.XmlEx.inflate
import com.chad.library.adapter4.BaseQuickAdapter
class AppBeanAdapter : BaseQuickAdapter<AppBean, AppBeanAdapter.AppHolder>() {
inner class AppHolder(view: View) : RecyclerView.ViewHolder(view)
var stopAction: ((pkg: String) -> Unit)? = null
override fun onBindViewHolder(holder: AppHolder, position: Int, item: AppBean?) {
if (item == null) return
val binding = ItemAppProcessBinding.bind(holder.itemView)
binding.iv.setImageDrawable(item.icon)
binding.tvName.text = item.name
binding.tvStop.setOnClickListener {
stopAction?.invoke(item.packageName)
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): AppHolder {
return AppHolder(R.layout.item_app_process.inflate(parent))
}
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ui.appprocess
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.graphics.Color
import android.net.Uri
import android.provider.Settings
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.view.View
import androidx.activity.addCallback
import androidx.lifecycle.lifecycleScope
import com.base.pdfviewerscannerwhite.ads.admob.AdmobInterstitialUtils
import com.base.pdfviewerscannerwhite.bean.AppBean
import com.base.pdfviewerscannerwhite.databinding.ActivityAppProcessBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.utils.AppPreferences
import com.base.pdfviewerscannerwhite.utils.BarUtils
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatSize
import com.base.pdfviewerscannerwhite.utils.RamUtils.ramPair
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.random.Random
class AppProcessActivity : BaseActivity<ActivityAppProcessBinding>() {
private val TAG = "com.base.pdfviewerscannerwhite.ui.appprocess.AppProcessActivity"
override val binding: ActivityAppProcessBinding by lazy {
ActivityAppProcessBinding.inflate(layoutInflater)
}
private lateinit var adapter: AppBeanAdapter
@SuppressLint("SetTextI18n")
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
// binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
adapter = AppBeanAdapter()
adapter.stopAction = { pkg ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", pkg, null)
intent.setData(uri)
startActivity(intent)
}
binding.rv.adapter = adapter
val ramPair = ramPair()
val percent = ((ramPair.first.toFloat() / ramPair.second.toFloat()) * 100).toInt()
binding.progressBar.progress = percent
binding.tvPercent.text = percent.toString()
binding.tvRamRate.text = ramPair.first.toFormatSize() + " / " + ramPair.second.toFormatSize()
AppPreferences.getInstance().put("last_process_use_time", System.currentTimeMillis())
initData()
}
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback {
AdmobInterstitialUtils.showInterstitialAd(this@AppProcessActivity) {
finishToMain()
}
}
binding.flFanhui.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
binding.tvBtn.setOnClickListener {
AdmobInterstitialUtils.showInterstitialAd(this) {
finish()
}
}
}
companion object {
fun isLaunchApp(context: Context, app: PackageInfo, filterSystem: Boolean = true): Boolean {
val flagSystem = (app.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) < 1
val flag = if (filterSystem) flagSystem else true
return flag && app.applicationInfo.packageName != context.packageName
}
@SuppressLint("QueryPermissionsNeeded")
fun fastGetAppIcon(context: Context): List<PackageInfo> {
val pm = context.packageManager
val packages = pm.getInstalledPackages(0).filter { isLaunchApp(context, it) }
return packages
}
}
@SuppressLint("QueryPermissionsNeeded")
private fun initData() = lifecycleScope.launch(Dispatchers.IO) {
val pm = packageManager
val packages = pm.getInstalledPackages(0)
val list = arrayListOf<AppBean>()
var totalCount = 0
var backAppCount = 0
packages.forEachIndexed { index, packageInfo ->
if (isLaunchApp(this@AppProcessActivity, packageInfo)) {
totalCount++
if (index % 2 == 0 && Random.nextBoolean()) {
val appBean = AppBean(
packageInfo.applicationInfo.loadIcon(pm),
packageInfo.applicationInfo.loadLabel(pm).toString(),
packageInfo.applicationInfo.packageName
)
list.add(appBean)
backAppCount++
}
}
}
launch(Dispatchers.Main) {
binding.progressBarLoading.visibility = View.GONE
adapter.submitList(list)
val text = "$backAppCount/$totalCount"
val spannableString = SpannableString(text)
val start = text.indexOf("$backAppCount")
val end = start + "$backAppCount".length
val colorSpan = ForegroundColorSpan(Color.parseColor("#0672EE"))
spannableString.setSpan(colorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
binding.tvRate.text = spannableString.toString()
}
}
}
\ No newline at end of file
......@@ -4,10 +4,12 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.base.pdfviewerscannerwhite.R
......@@ -25,7 +27,7 @@ import com.base.pdfviewerscannerwhite.bean.ConstObject.SHORTCUT_SPLIT_PDF
import com.base.pdfviewerscannerwhite.bean.ConstObject.mainStartTimes
import com.base.pdfviewerscannerwhite.bean.ConstObject.todayShowNotificationDialog
import com.base.pdfviewerscannerwhite.bean.DocumentBean
import com.base.pdfviewerscannerwhite.databinding.ActivityMain2Binding
import com.base.pdfviewerscannerwhite.databinding.ActivityMainBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.helper.MyApplication
import com.base.pdfviewerscannerwhite.ui.document.excel.ExcelActivity
......@@ -42,6 +44,7 @@ import com.base.pdfviewerscannerwhite.ui.view.DialogView.showStoragePermission
import com.base.pdfviewerscannerwhite.ui.view.PdfDialog.showPdfPwdDialog
import com.base.pdfviewerscannerwhite.ui.view.RateDialog.showRateDialog
import com.base.pdfviewerscannerwhite.utils.AppPreferences
import com.base.pdfviewerscannerwhite.utils.BarUtils
import com.base.pdfviewerscannerwhite.utils.IntentShareUtils.shareMutDocuments
import com.base.pdfviewerscannerwhite.utils.LogEx
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkNotificationPermission
......@@ -50,12 +53,12 @@ import com.base.pdfviewerscannerwhite.utils.ShortcutUtils.addDeskShortCut
import com.base.pdfviewerscannerwhite.utils.updateMediaStore
import java.io.File
class MainActivity : BaseActivity<ActivityMain2Binding>(), MainView {
class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
private val TAG = "MainActivity"
lateinit var mainPresenter: MainPresenter
override val binding: ActivityMain2Binding by lazy {
ActivityMain2Binding.inflate(layoutInflater)
override val binding: ActivityMainBinding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
private val documentFragment: DocumentFragment by lazy {
DocumentFragment(DOCUMENT_DATA_TYPE)
......@@ -74,6 +77,9 @@ class MainActivity : BaseActivity<ActivityMain2Binding>(), MainView {
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.WHITE)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
mainPresenter = MainPresenter(this, this, lifecycleScope)
mainPresenter.initScannerLauncher(this)
......
package com.base.pdfviewerscannerwhite.ui.main
import android.annotation.SuppressLint
import android.app.usage.StorageStatsManager
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.StatFs
import android.os.storage.StorageManager
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.base.pdfviewerscannerwhite.bean.ConstObject.DO_LOCK_PDF
import com.base.pdfviewerscannerwhite.bean.ConstObject.DO_MERGE_PDF
......@@ -9,13 +16,23 @@ import com.base.pdfviewerscannerwhite.bean.ConstObject.DO_SPLIT_PDF
import com.base.pdfviewerscannerwhite.bean.ConstObject.DO_UNLOCK_PDF
import com.base.pdfviewerscannerwhite.databinding.FragmentToolBinding
import com.base.pdfviewerscannerwhite.helper.BaseFragment
import com.base.pdfviewerscannerwhite.ui.appprocess.AppProcessActivity
import com.base.pdfviewerscannerwhite.ui.cleanjunk.ScanJunkActivity
import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfActivity
import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfBoxUtils
import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfSelectActivity
import com.base.pdfviewerscannerwhite.ui.set.SetActivity
import com.base.pdfviewerscannerwhite.ui.view.PdfDialog.showPdfPwdDialog
import com.base.pdfviewerscannerwhite.ui.view.ProgressBean
import com.base.pdfviewerscannerwhite.ui.weather.WeatherInterface
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatSize
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission
import com.base.pdfviewerscannerwhite.utils.getMediaAudioCountSize
import com.base.pdfviewerscannerwhite.utils.getMediaPhotoCountSize
import com.base.pdfviewerscannerwhite.utils.getMediaVideoCountSize
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
class ToolFragment : BaseFragment<FragmentToolBinding>() {
......@@ -96,6 +113,82 @@ class ToolFragment : BaseFragment<FragmentToolBinding>() {
mainActivity ?: return@setOnClickListener
mainActivity.useGmsScanFunction()
}
binding.llScan.setOnClickListener {
val mainActivity = (requireActivity() as MainActivity?)
mainActivity ?: return@setOnClickListener
mainActivity.useGmsScanFunction()
}
binding.llProcess.setOnClickListener {
startActivity(Intent(requireContext(), AppProcessActivity::class.java))
}
binding.tvClean.setOnClickListener {
startActivity(Intent(requireContext(), ScanJunkActivity::class.java))
}
binding.llWeather.setOnClickListener {
startActivity(Intent(requireContext(), WeatherInterface::class.java))
}
}
override fun onResume() {
super.onResume()
if (requireContext().checkStorePermission()) {
refreshData()
}
}
var usedBytes: Long = 0
var totalBytes: Long = 0
private val progressList = arrayListOf<ProgressBean>()
@SuppressLint("SetTextI18n")
private fun refreshData() = lifecycleScope.launch(Dispatchers.IO) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val storageStatsManager = requireContext().getSystemService(AppCompatActivity.STORAGE_STATS_SERVICE) as StorageStatsManager
totalBytes = storageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT)
usedBytes = totalBytes - storageStatsManager.getFreeBytes(StorageManager.UUID_DEFAULT)
} else {
val path1: File = Environment.getDataDirectory()
val stat1 = StatFs(path1.path)
val path2: File = Environment.getExternalStorageDirectory()
val stat2 = StatFs(path2.path)
totalBytes = (stat1.totalBytes + stat2.totalBytes)
usedBytes = ((stat1.totalBytes + stat2.totalBytes) - (stat1.availableBytes + stat2.availableBytes))
}
lifecycleScope.launch(Dispatchers.Main) {
binding.tvUsedStorage.text = usedBytes.toFormatSize()
binding.tvTotalStorage.text = " / ${totalBytes.toFormatSize()}"
binding.tvPercent.text = "${usedBytes * 100 / totalBytes}"
}
val videoPair = requireContext().getMediaVideoCountSize()
val picturePair = requireContext().getMediaPhotoCountSize()
val audioPair = requireContext().getMediaAudioCountSize()
val totalAngle = (usedBytes.toFloat() / totalBytes.toFloat()) * 360f
val appSize = usedBytes - videoPair.second - picturePair.second - audioPair.second
progressList.clear()
val appAngle = (appSize * totalAngle / usedBytes).toFloat()
val appBean = ProgressBean(0f, appAngle, "#FD412F")
progressList.add(appBean)
val videoAngle = (usedBytes * 0.01 * totalAngle / usedBytes)
val videoBean = ProgressBean(appBean.sweepAngle, (appBean.sweepAngle + videoAngle).toFloat(), "#FDC734")
progressList.add(videoBean)
val photoAngle = (usedBytes * 0.01 * totalAngle / usedBytes)
val photoBean = ProgressBean(videoBean.sweepAngle, (videoBean.sweepAngle + photoAngle).toFloat(), "#00BE78")
progressList.add(photoBean)
val audioAngle = (usedBytes * 0.01 * totalAngle / usedBytes)
val audioBean = ProgressBean(photoBean.sweepAngle, (photoBean.sweepAngle + audioAngle).toFloat(), "#8238FD")
progressList.add(audioBean)
progressList.reverse()
launch(Dispatchers.Main) {
binding.colorProgress.animateProgress(progressList)
}
}
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ui.view
import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator
import com.base.pdfviewerscannerwhite.R
class ColorProgress : View {
private lateinit var ringPaint: Paint//圆环笔
private var centerX = 0f
private var centerY = 0f
private var radius = 0f
private var strokeWidth = 0f // 圆环的宽度
private var margin = 5f
private lateinit var ringRectF: RectF
private lateinit var progressRectF: RectF
private lateinit var progressPaint: Paint
private var listProgressBean: List<ProgressBean> = listOf()
private var currentAngle = 0f
constructor(context: Context) : super(context) {
initPaint(context)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initPaint(context)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initPaint(context)
}
var finishAnimation: (() -> Unit)? = null
private fun initPaint(context: Context) {
strokeWidth = context.resources.getDimension(R.dimen.dp_9)
ringPaint = Paint()
ringPaint.isAntiAlias = true
ringPaint.style = Paint.Style.STROKE
ringPaint.setColor(Color.parseColor("#E6E7EC"))
ringPaint.strokeWidth = strokeWidth
progressPaint = Paint()
progressPaint.isAntiAlias = true
progressPaint.style = Paint.Style.STROKE
progressPaint.strokeWidth = strokeWidth
progressPaint.strokeCap = Paint.Cap.ROUND
// 初始化圆的中心点和半径
centerX = width / 2.0f
centerY = height / 2.0f
radius = (centerX.coerceAtMost(centerY) - strokeWidth / 2) - margin
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
centerX = w / 2.0f
centerY = h / 2.0f
radius = (centerX.coerceAtMost(centerY) - strokeWidth / 2) - margin
ringRectF = RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
progressRectF = RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// 绘制圆环
canvas.drawOval(ringRectF, ringPaint)
listProgressBean.forEachIndexed { index, progressBean ->
progressPaint.setColor(Color.parseColor(progressBean.color))
if (index != 0) {
val lastProgressBean: ProgressBean = listProgressBean[index - 1]
if (currentAngle <= progressBean.sweepAngle) {
canvas.drawArc(progressRectF, -90f, currentAngle, false, progressPaint)
progressBean.draw = true
} else if (lastProgressBean.draw) {
canvas.drawArc(progressRectF, -90f, progressBean.sweepAngle, false, progressPaint)
progressBean.draw = true
}
} else {
if (currentAngle >= progressBean.startAngle) {
canvas.drawArc(progressRectF, -90f, currentAngle, false, progressPaint)
progressBean.draw = true
}
}
}
}
private fun setProgress(angle: Float) {
currentAngle = angle
invalidate()
}
fun animateProgress(list: List<ProgressBean>) {
listProgressBean = list
val totalAngle = list.maxOf { it.sweepAngle }
val progressAnimator = ValueAnimator.ofFloat(0f, totalAngle)
progressAnimator.interpolator = LinearInterpolator() // 平滑插值器
progressAnimator.setDuration(1500) // 动画持续时间1000毫秒
progressAnimator.addUpdateListener { animation ->
val animatedValue = animation.getAnimatedValue() as Float
setProgress(animatedValue)
}
progressAnimator.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
}
override fun onAnimationEnd(animation: Animator) {
finishAnimation?.invoke()
}
override fun onAnimationCancel(animation: Animator) {
}
override fun onAnimationRepeat(animation: Animator) {
}
})
progressAnimator.start()
}
}
data class ProgressBean(
val startAngle: Float = 0f,
val sweepAngle: Float = 0f,
var color: String = ""
) {
var draw = false
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ui.weather
import android.annotation.SuppressLint
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.RecyclerView
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.ads.admob.AdmobInterstitialUtils
import com.base.pdfviewerscannerwhite.ads.admob.AdmobNativeUtils
import com.base.pdfviewerscannerwhite.bean.ListBean
import com.base.pdfviewerscannerwhite.bean.WeatherBean
import com.base.pdfviewerscannerwhite.databinding.ActivityWeatherBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.helper.WeatherUtils
import com.base.pdfviewerscannerwhite.utils.BarUtils
import kotlin.random.Random
@SuppressLint("SimpleDateFormat")
class WeatherInterface : BaseActivity<ActivityWeatherBinding>() {
override val binding: ActivityWeatherBinding by lazy {
ActivityWeatherBinding.inflate(layoutInflater)
}
var wBean: WeatherBean? = null
override fun initView() {
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
getData()
AdmobNativeUtils.showNativeAd(this, binding.idFlAd)
}
override fun initListener() {
binding.idBack.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
finishToMain()
}
})
}
private fun getData() {
wBean = WeatherUtils.getWeatherEntity()
if (wBean != null) {
setViews()
} else {
WeatherUtils.requestWeatherData()
}
binding.root.postDelayed({
AdmobInterstitialUtils.showInterstitialAd(this, false) {
binding.idFlLoading.isVisible = false
}
}, Random.nextLong(800, 2000))
}
@SuppressLint("SetTextI18n")
private var wertherList = mutableListOf<ListBean>()
@SuppressLint("SetTextI18n")
private fun setViews() {
binding.idTvCity.text = wBean?.city
binding.idTvDate.text = wBean?.list?.get(0)?.fxDate
binding.idTvTmp.text = "${wBean?.list?.get(0)?.tempMax}°"
binding.idTvHumidity.text = "${wBean?.list?.get(0)?.humidity}%"
binding.idTvWind.text = "${wBean?.list?.get(0)?.windScaleDay}"
binding.idTvPressure.text = "${wBean?.list?.get(0)?.pressure}hPa"
when ((wBean?.list?.get(0)?.iconDay)?.toInt()?.let { WeatherUtils.getWeatherType(it) }) {
"Sunny day" -> {
binding.idImgW.setImageResource(R.mipmap.d_qing)
}
"Cloudy day" -> {
binding.idImgW.setImageResource(R.mipmap.d_yin)
}
"Rainy day" -> {
binding.idImgW.setImageResource(R.mipmap.d_dayu)
}
"Snowy day" -> {
binding.idImgW.setImageResource(R.mipmap.d_xiaxue)
}
"Greasy day" -> {
binding.idImgW.setImageResource(R.mipmap.d_wumaishachengbao)
}
"Unknown" -> {
binding.idImgW.setImageResource(R.mipmap.d_qing)
}
}
wertherList.clear()
wBean?.list?.let { wertherList.addAll(it) }
binding.idRlWeather.run {
adapter = object : RecyclerView.Adapter<ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(this@WeatherInterface)
.inflate(R.layout.item_layout_wheather, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return wertherList.size
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = wertherList[position]
when (WeatherUtils.getWeatherType(item.iconDay.toInt())) {
"Sunny day" -> {
holder.ivIcon.setImageResource(R.mipmap.x_qing)
}
"Cloudy day" -> {
holder.ivIcon.setImageResource(R.mipmap.x_yin)
}
"Rainy day" -> {
holder.ivIcon.setImageResource(R.mipmap.x_dayu)
}
"Snowy day" -> {
holder.ivIcon.setImageResource(R.mipmap.x_xiaxue)
}
"Greasy day" -> {
holder.ivIcon.setImageResource(R.mipmap.x_wumaishachengbao)
}
"Unknown" -> {
holder.ivIcon.setImageResource(R.mipmap.x_qing)
}
}
holder.tvTime.text = item.fxDate
holder.tvMaxTmp.text = "${item.tempMax}°/"
holder.tvMinTmp.text = "${item.tempMin}°"
}
}
}
}
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val ivIcon: ImageView
val tvTime: TextView
val tvMaxTmp: TextView
val tvMinTmp: TextView
init {
ivIcon = view.findViewById(R.id.id_img_icon)
tvTime = view.findViewById(R.id.id_tv_time)
tvMaxTmp = view.findViewById(R.id.id_tv_max_tmp)
tvMinTmp = view.findViewById(R.id.id_tv_min_tmp)
}
}
}
package com.base.pdfviewerscannerwhite.utils
import android.app.ActivityManager
import android.content.Context
object RamUtils {
fun Context.ramPair(): Pair<Long, Long> {
val outInfo = ActivityManager.MemoryInfo()
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager?
activityManager!!.getMemoryInfo(outInfo)
val totalMem = outInfo.totalMem
val usedMem = outInfo.totalMem - outInfo.availMem
return Pair(usedMem, totalMem)
}
}
\ 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="8dp" />
<solid android:color="#00BF79" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#26000000" />
<corners android:radius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#8338FF" />
<corners android:radius="8dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/xuan" android:state_selected="true" />
<item android:drawable="@mipmap/weixuan" android:state_selected="false" />
</selector>
\ 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="18dp" />
<solid android:color="#E7EEF6" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F95242" />
<corners android:radius="17dp" />
</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="8dp" />
<solid android:color="#FF412F" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFC834" />
<corners android:radius="8dp" />
</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">
<shape>
<solid android:color="#33FFFFFF" />
<corners android:radius="4dp" />
</shape>
</item>
<!-- 设置进度条颜色 -->
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="4dp" />
<solid android:color="@color/white" />
</shape>
</clip>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#4EA082">
<LinearLayout
android:id="@+id/ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<FrameLayout
android:id="@+id/fl_fanhui"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@mipmap/fanhui_w"
tools:ignore="ContentDescription,MissingPrefix" />
</FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="App Process"
android:textColor="@color/white"
android:textSize="19sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>
<TextView
android:id="@+id/tv_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:layout_marginTop="20dp"
android:text="Used Already"
android:textColor="@color/white"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textColor="@color/white"
android:textSize="50sp"
app:layout_constraintStart_toStartOf="@id/tv_tip"
app:layout_constraintTop_toBottomOf="@id/tv_tip"
tools:text="55.6" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.5dp"
android:text="%"
android:textColor="@color/white"
android:textSize="45sp"
app:layout_constraintBottom_toBottomOf="@id/tv_percent"
app:layout_constraintStart_toEndOf="@id/tv_percent"
app:layout_constraintTop_toTopOf="@id/tv_percent"
tools:ignore="HardcodedText" />
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="15dp"
android:layout_marginHorizontal="22dp"
android:max="100"
android:progressDrawable="@drawable/progressbar_appprocess"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_percent"
app:layout_constraintVertical_bias="0.3"
tools:progress="50" />
<TextView
android:id="@+id/tv_ram_rate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:gravity="center_vertical|end"
android:textColor="@color/white"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@id/progress_bar"
app:layout_constraintEnd_toEndOf="@id/progress_bar"
tools:text="10 GB / 20 GB" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="-20dp"
android:background="@drawable/bg_ffffff_tlr25"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:layout_marginStart="18dp"
android:text="Backend Application"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_rate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:layout_marginEnd="18dp"
android:text="32/32"
android:textSize="16sp"
tools:ignore="HardcodedText" />
</FrameLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="20dp"
android:background="#E5E6EB" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_app_process" />
<ProgressBar
android:id="@+id/progress_bar_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
<TextView
android:id="@+id/tv_btn"
android:layout_width="338dp"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:layout_marginBottom="25dp"
android:background="@drawable/bg_0571ed_25"
android:gravity="center"
android:text="Complete"
android:textColor="@color/white"
android:textSize="18sp"
tools:ignore="HardcodedText" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?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">
<androidx.cardview.widget.CardView
android:id="@+id/card"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginVertical="15dp"
android:layout_marginStart="26dp"
app:cardCornerRadius="10dp"
app:cardElevation="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="ContentDescription" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:textColor="@color/black"
android:textSize="17sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/tv_stop"
app:layout_constraintStart_toEndOf="@id/card"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:text="Stop"
android:textColor="#0571ED"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@id/card"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_name"
app:layout_constraintTop_toTopOf="@id/card"
tools:ignore="HardcodedText" />
<View
android:layout_width="0dp"
android:layout_height="1px"
android:layout_marginBottom="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/card" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="16dp">
<TextView
android:id="@+id/id_tv_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:layout_weight="1"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="Today, 25 Jun" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/id_img_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginEnd="22dp"
android:src="@mipmap/x_qing" />
<TextView
android:id="@+id/id_tv_max_tmp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="17sp"
tools:text="32°/" />
<TextView
android:id="@+id/id_tv_min_tmp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="14dp"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="12°" />
</LinearLayout>
\ No newline at end of file
......@@ -6,4 +6,5 @@
<dimen name="dp_146">146dp</dimen>
<dimen name="dp_345">345dp</dimen>
<dimen name="dp_5">5dp</dimen>
<dimen name="dp_9">9dp</dimen>
</resources>
\ No newline at end of file
......@@ -108,5 +108,11 @@
<string name="always">Always </string>
<string name="as_the_default_reader">It is set as the default reader.</string>
<string name="image_pdf">Image Pdf</string>
<string name="process">Process</string>
<string name="_7_day_weather_forecast">7 Day weather forecast</string>
<string name="wait_a_moment">Wait a moment...</string>
<string name="humidity">Humidity</string>
<string name="wind">Wind</string>
<string name="pressure">Pressure</string>
</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