Commit 9339dee9 authored by wanglei's avatar wanglei

...ui

parent 979002ed
...@@ -16,10 +16,8 @@ import com.base.datarecovery.bean.ConstObject.ifAgreePrivacy ...@@ -16,10 +16,8 @@ import com.base.datarecovery.bean.ConstObject.ifAgreePrivacy
import com.base.datarecovery.databinding.ActivitySplashBinding import com.base.datarecovery.databinding.ActivitySplashBinding
import com.base.datarecovery.help.BaseActivity import com.base.datarecovery.help.BaseActivity
import com.base.datarecovery.help.ConfigHelper import com.base.datarecovery.help.ConfigHelper
import com.base.datarecovery.help.UmpHelp.requestUMP
import com.base.datarecovery.utils.BarUtils import com.base.datarecovery.utils.BarUtils
import com.base.datarecovery.utils.LogEx import com.base.datarecovery.utils.LogEx
import com.base.datarecovery.utils.SPUtils
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
...@@ -99,17 +97,12 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>() { ...@@ -99,17 +97,12 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>() {
if (oneClickStart) { if (oneClickStart) {
return@setOnClickListener return@setOnClickListener
} }
(application as MyApplication).initApp()
oneClickStart = true oneClickStart = true
ifAgreePrivacy = true ifAgreePrivacy = true
binding.llStart.visibility = View.GONE binding.llStart.visibility = View.GONE
binding.llProgress.visibility = View.VISIBLE binding.llProgress.visibility = View.VISIBLE
startProgress() startProgress()
this.requestUMP { flag ->
if (flag) {
(application as MyApplication).initApp()
}
}
} }
} }
......
package com.base.datarecovery.activity.privacyspace package com.base.datarecovery.activity.privacyspace
import android.annotation.SuppressLint
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Environment
import androidx.activity.enableEdgeToEdge import android.view.View
import androidx.appcompat.app.AppCompatActivity import android.widget.Toast
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import com.base.datarecovery.R import androidx.lifecycle.lifecycleScope
import com.base.datarecovery.adapter.MediaSubAdapter
import com.base.datarecovery.bean.MediaBean
import com.base.datarecovery.databinding.ActivityPrivacyManageBinding import com.base.datarecovery.databinding.ActivityPrivacyManageBinding
import com.base.datarecovery.help.BaseActivity import com.base.datarecovery.help.BaseActivity
import com.base.datarecovery.help.FileHelp.loadFileByFilter
import com.base.datarecovery.help.MediaStoreHelp.updateMediaStore
import com.base.datarecovery.utils.BarUtils import com.base.datarecovery.utils.BarUtils
import com.base.datarecovery.utils.LogEx
import com.base.datarecovery.view.DialogViews.showDeletePermanentlyDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
class PrivacyManageActivity : BaseActivity<ActivityPrivacyManageBinding>() { class PrivacyManageActivity : BaseActivity<ActivityPrivacyManageBinding>() {
private val TAG = "PrivacyManageActivity"
private var mediaType: String = ""
private lateinit var mediaSubAdapter: MediaSubAdapter
override val binding: ActivityPrivacyManageBinding by lazy { override val binding: ActivityPrivacyManageBinding by lazy {
ActivityPrivacyManageBinding.inflate(layoutInflater) ActivityPrivacyManageBinding.inflate(layoutInflater)
...@@ -24,6 +35,88 @@ class PrivacyManageActivity : BaseActivity<ActivityPrivacyManageBinding>() { ...@@ -24,6 +35,88 @@ class PrivacyManageActivity : BaseActivity<ActivityPrivacyManageBinding>() {
BarUtils.setStatusBarLightMode(this, true) BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT) BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight()) binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
mediaType = intent?.extras?.getString("mediaType") ?: ""
mediaSubAdapter = MediaSubAdapter()
binding.rv.adapter = mediaSubAdapter
initData()
}
@SuppressLint("SetTextI18n")
override fun initListener() {
binding.llDownload.setOnClickListener {
downloadCopy()
}
binding.llDelete.setOnClickListener {
deleteFilesDirMedia()
}
binding.tvSelectAll.setOnClickListener {
binding.tvSelectAll.isSelected = !binding.tvSelectAll.isSelected
mediaSubAdapter.toggleSelect(binding.tvSelectAll.isSelected)
if (binding.tvSelectAll.isSelected) {
binding.tvSelectAll.text = "Unselect All"
} else {
binding.tvSelectAll.text = "Select All"
}
}
}
private fun deleteFilesDirMedia() {
showDeletePermanentlyDialog {
lifecycleScope.launch(Dispatchers.IO) {
val list = mediaSubAdapter.getSelectData()
list.forEach {
runCatching { File(it.path).delete() }
}
launch(Dispatchers.Main) {
Toast.makeText(this@PrivacyManageActivity, "success", Toast.LENGTH_SHORT).show()
mediaSubAdapter.removeData(list)
}
}
}
}
private fun downloadCopy() = lifecycleScope.launch(Dispatchers.IO) {
mediaSubAdapter.getSelectData().forEach { bean ->
runCatching {
val file = File(bean.path)
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
file.copyTo(File(dir, file.name))
}
}
this@PrivacyManageActivity.updateMediaStore()
launch(Dispatchers.Main) {
Toast.makeText(this@PrivacyManageActivity, "success", Toast.LENGTH_SHORT).show()
mediaSubAdapter.toggleSelect(false)
}
}
private fun initData() {
val dir = getFilesMediaDir()
if (!dir.exists()) {
dir.mkdirs()
}
val list = arrayListOf<MediaBean>()
lifecycleScope.loadFileByFilter(folder = dir, filter = { true }, onDo = {
LogEx.logDebug(TAG, "$it")
list.add(MediaBean(it.absolutePath))
}, onFinish = {
if (list.isNotEmpty()) {
binding.rv.visibility = View.VISIBLE
mediaSubAdapter.setData(list)
}
})
}
private fun getFilesMediaDir(): File {
return if (mediaType == "Photos") {
File(filesDir, "photos")
} else {
File(filesDir, "videos")
}
} }
} }
\ No newline at end of file
...@@ -43,8 +43,11 @@ class MediaAdapter(private val clickAction: (Pair<Boolean, List<MediaBean>>) -> ...@@ -43,8 +43,11 @@ class MediaAdapter(private val clickAction: (Pair<Boolean, List<MediaBean>>) ->
binding.ivSelector.isSelected = bean.isSelect binding.ivSelector.isSelected = bean.isSelect
val subAdapter = MediaSubAdapter(bean.beans) val subAdapter = MediaSubAdapter().apply {
subClickAction = { clickAction.invoke(this@MediaAdapter.getSelectData()) }
}
binding.rvMediaColumns.adapter = subAdapter binding.rvMediaColumns.adapter = subAdapter
subAdapter.setData(bean.beans)
binding.flSelect.setOnClickListener { binding.flSelect.setOnClickListener {
bean.isSelect = !bean.isSelect bean.isSelect = !bean.isSelect
...@@ -75,44 +78,6 @@ class MediaAdapter(private val clickAction: (Pair<Boolean, List<MediaBean>>) -> ...@@ -75,44 +78,6 @@ class MediaAdapter(private val clickAction: (Pair<Boolean, List<MediaBean>>) ->
return Pair(allSelect, pathList) return Pair(allSelect, pathList)
} }
private inner class MediaSubAdapter(val list: List<MediaBean>) : RecyclerView.Adapter<MediaSubAdapter.Sub>() {
inner class Sub(view: View) : ViewHolder(view) {
val iv = view.findViewById<ImageView>(R.id.iv)
val ivSelector = view.findViewById<ImageView>(R.id.iv_selector)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Sub {
return Sub(R.layout.item_media_grid_select.inflate(parent))
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: Sub, position: Int) {
}
override fun onBindViewHolder(holder: Sub, position: Int, payloads: MutableList<Any>) {
val context = holder.itemView.context
val data = list[position]
if (payloads.isEmpty()) {
Glide.with(context).load(data.path).centerCrop().into(holder.iv)
holder.ivSelector.isSelected = data.isSelect
holder.itemView.setOnClickListener {
data.isSelect = !data.isSelect
holder.ivSelector.isSelected = data.isSelect
this.notifyItemChanged(position, "hh")
clickAction.invoke(getSelectData())
}
} else {
holder.ivSelector.isSelected = data.isSelect
super.onBindViewHolder(holder, position, payloads)
}
}
}
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
fun toggleAllSelect(select: Boolean) { fun toggleAllSelect(select: Boolean) {
......
package com.base.datarecovery.adapter
import android.annotation.SuppressLint
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.base.datarecovery.R
import com.base.datarecovery.bean.MediaBean
import com.base.datarecovery.view.XmlEx.inflate
import com.bumptech.glide.Glide
class MediaSubAdapter : RecyclerView.Adapter<MediaSubAdapter.Sub>() {
private val subList: ArrayList<MediaBean> = arrayListOf()
var subClickAction: (() -> Unit)? = null
inner class Sub(view: View) : RecyclerView.ViewHolder(view) {
val iv = view.findViewById<ImageView>(R.id.iv)
val ivSelector = view.findViewById<ImageView>(R.id.iv_selector)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Sub {
return Sub(R.layout.item_media_grid_select.inflate(parent))
}
override fun getItemCount(): Int {
return subList.size
}
override fun onBindViewHolder(holder: Sub, position: Int) {
}
override fun onBindViewHolder(holder: Sub, position: Int, payloads: MutableList<Any>) {
val context = holder.itemView.context
val data = subList[position]
if (payloads.isEmpty()) {
Glide.with(context).load(data.path).centerCrop().into(holder.iv)
holder.ivSelector.isSelected = data.isSelect
holder.itemView.setOnClickListener {
data.isSelect = !data.isSelect
holder.ivSelector.isSelected = data.isSelect
this.notifyItemChanged(position, "hh")
subClickAction?.invoke()
}
} else {
holder.ivSelector.isSelected = data.isSelect
super.onBindViewHolder(holder, position, payloads)
}
}
@SuppressLint("NotifyDataSetChanged")
fun setData(list: List<MediaBean>) {
subList.clear()
subList.addAll(list)
notifyDataSetChanged()
}
fun getSelectData(): List<MediaBean> {
return subList.filter { it.isSelect }
}
@SuppressLint("NotifyDataSetChanged")
fun removeData(list: List<MediaBean>) {
subList.removeAll(list.toSet())
notifyDataSetChanged()
}
@SuppressLint("NotifyDataSetChanged")
fun toggleSelect(b: Boolean) {
subList.forEach { it.isSelect=b }
notifyDataSetChanged()
}
}
\ No newline at end of file
package com.base.datarecovery.bean package com.base.datarecovery.bean
import android.net.Uri
data class MediaTimeBean( data class MediaTimeBean(
val time: String = "", val time: String = "",
......
...@@ -5,6 +5,7 @@ import android.view.View ...@@ -5,6 +5,7 @@ import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.base.datarecovery.activity.privacyspace.PrivacyImportActivity import com.base.datarecovery.activity.privacyspace.PrivacyImportActivity
import com.base.datarecovery.activity.privacyspace.PrivacyManageActivity
import com.base.datarecovery.activity.privacyspace.PrivacySpaceActivity import com.base.datarecovery.activity.privacyspace.PrivacySpaceActivity
import com.base.datarecovery.adapter.FileGridAdapter import com.base.datarecovery.adapter.FileGridAdapter
import com.base.datarecovery.databinding.FragmentPrivacyPageBinding import com.base.datarecovery.databinding.FragmentPrivacyPageBinding
...@@ -20,7 +21,7 @@ import java.io.File ...@@ -20,7 +21,7 @@ import java.io.File
import kotlin.random.Random import kotlin.random.Random
class PrivacyPageFragment( class PrivacyPageFragment(
val type: String val mediaType: String
) : BaseFragment<FragmentPrivacyPageBinding>() { ) : BaseFragment<FragmentPrivacyPageBinding>() {
private val TAG = "PrivacyPageFragment" private val TAG = "PrivacyPageFragment"
...@@ -79,12 +80,17 @@ class PrivacyPageFragment( ...@@ -79,12 +80,17 @@ class PrivacyPageFragment(
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
}, Random.nextLong(2500)) }, Random.nextLong(2500))
} }
binding.tvManager.setOnClickListener {
startActivity(Intent(requireContext(), PrivacyManageActivity::class.java).apply {
putExtra("mediaType", mediaType)
})
}
} }
private fun initData() { private fun initData() {
val dir = if (type == "Photos") { val dir = if (mediaType == "Photos") {
File(requireContext().filesDir, "photos") File(requireContext().filesDir, "photos")
} else { } else {
File(requireContext().filesDir, "videos") File(requireContext().filesDir, "videos")
......
package com.base.datarecovery.help
import android.app.Activity
import com.google.android.ump.ConsentRequestParameters
import com.google.android.ump.FormError
import com.google.android.ump.UserMessagingPlatform
object UmpHelp {
fun Activity.requestUMP(gatherAction: (flag: Boolean) -> Unit) {
val params = ConsentRequestParameters.Builder()
// 指示用户是否低于同意年龄; true 低于同意年龄
// 未满同意年龄的用户不会收到 GDPR 消息表单
.setTagForUnderAgeOfConsent(false)
.build()
val consentInformation = UserMessagingPlatform.getConsentInformation(this)
consentInformation.requestConsentInfoUpdate(
this, params, {
UserMessagingPlatform.loadAndShowConsentFormIfRequired(this) { loadAndShowError: FormError? ->
if (loadAndShowError != null) {
// Consent gathering failed.
gatherAction.invoke(false)
}
// Consent has been gathered.
if (consentInformation.canRequestAds()) {
// 授权完成,初始化SDK
gatherAction.invoke(true)
}
}
},
{ requestConsentError: FormError? ->
gatherAction.invoke(false)
})
if (consentInformation.canRequestAds()) {
// 授权完成,初始化SDK
gatherAction.invoke(true)
}
}
}
\ No newline at end of file
...@@ -6,11 +6,12 @@ import android.view.Gravity ...@@ -6,11 +6,12 @@ import android.view.Gravity
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
class CustomDialog(context: Context, layoutId: Int) : Dialog(context) { class CustomDialog(context: Context, layoutId: Int? = null, view: View? = null) : Dialog(context) {
private var countdownText: TextView? = null private var countdownText: TextView? = null
init { init {
setContentView(layoutId) layoutId?.let { setContentView(it) }
view?.let { setContentView(it) }
val window = window val window = window
window?.apply { window?.apply {
setGravity(Gravity.CENTER) setGravity(Gravity.CENTER)
......
...@@ -14,13 +14,17 @@ import androidx.lifecycle.LifecycleCoroutineScope ...@@ -14,13 +14,17 @@ import androidx.lifecycle.LifecycleCoroutineScope
import com.base.datarecovery.R import com.base.datarecovery.R
import com.base.datarecovery.bean.ConstObject.rememberOption import com.base.datarecovery.bean.ConstObject.rememberOption
import com.base.datarecovery.databinding.DialogCameraSettingBinding import com.base.datarecovery.databinding.DialogCameraSettingBinding
import com.base.datarecovery.databinding.DialogDeletePermanentlyBinding
import com.base.datarecovery.databinding.DialogImageTakeBinding import com.base.datarecovery.databinding.DialogImageTakeBinding
import com.base.datarecovery.databinding.DialogPermissonOpenBinding import com.base.datarecovery.databinding.DialogPermissonOpenBinding
import com.base.datarecovery.databinding.DialogRecoveringBinding import com.base.datarecovery.databinding.DialogRecoveringBinding
import com.base.datarecovery.databinding.DialogRemoveFileTipBinding import com.base.datarecovery.databinding.DialogRemoveFileTipBinding
import com.base.datarecovery.utils.LogEx import com.base.datarecovery.utils.LogEx
import com.base.datarecovery.view.DialogViews.showCameraSettingDialog import com.base.datarecovery.view.DialogViews.showCameraSettingDialog
import com.base.datarecovery.view.DialogViews.showPinReEnterDialog
import com.base.datarecovery.view.DialogViews.showRecoveringDialog import com.base.datarecovery.view.DialogViews.showRecoveringDialog
import com.base.datarecovery.view.DialogViews.showRemoveOriginalTip
import com.base.datarecovery.view.XmlEx.inflate
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
...@@ -185,12 +189,16 @@ object DialogViews { ...@@ -185,12 +189,16 @@ object DialogViews {
fun Context.showRemoveOriginalTip(click: (isRememberOption: Boolean, isRemove: Boolean) -> Unit) { fun Context.showRemoveOriginalTip(click: (isRememberOption: Boolean, isRemove: Boolean) -> Unit) {
val binding = DialogRemoveFileTipBinding.inflate(LayoutInflater.from(this)) val binding = DialogRemoveFileTipBinding.inflate(LayoutInflater.from(this))
val dialog = AlertDialog.Builder(this, R.style.CustomAlertDialogStyle).setView(binding.root).create() val dialog = AlertDialog.Builder(this, R.style.CustomAlertDialogStyle).create()
dialog.setView(binding.root)
dialog.setContentView(binding.root) dialog.setContentView(binding.root)
dialog.setCanceledOnTouchOutside(false) dialog.setCanceledOnTouchOutside(false)
dialog.show() dialog.show()
val params = dialog.window?.attributes
params?.width = resources.getDimensionPixelOffset(R.dimen.dp_300)
dialog.window?.attributes = params
binding.ivSelector.setOnClickListener { binding.ivSelector.setOnClickListener {
binding.ivSelector.isSelected = !binding.ivSelector.isSelected binding.ivSelector.isSelected = !binding.ivSelector.isSelected
...@@ -213,4 +221,24 @@ object DialogViews { ...@@ -213,4 +221,24 @@ object DialogViews {
return dialog return dialog
} }
fun Context.showDeletePermanentlyDialog(deleteAction: () -> Unit) {
val binding = DialogDeletePermanentlyBinding.inflate(LayoutInflater.from(this))
val dialog = AlertDialog.Builder(this, R.style.CustomAlertDialogStyle).create()
dialog.setView(binding.root)
dialog.show()
val params = dialog.window?.attributes
params?.width = resources.getDimensionPixelOffset(R.dimen.dp_300)
dialog.window?.attributes = params
binding.tvDelete.setOnClickListener {
dialog.cancel()
deleteAction.invoke()
}
binding.tvCancel.setOnClickListener {
dialog.cancel()
}
}
} }
...@@ -69,7 +69,8 @@ ...@@ -69,7 +69,8 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="#577DFD"> android:background="#577DFD"
tools:ignore="DisableBaselineAlignment">
<LinearLayout <LinearLayout
android:id="@+id/ll_download" android:id="@+id/ll_download"
...@@ -77,7 +78,8 @@ ...@@ -77,7 +78,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginVertical="15dp" android:layout_marginVertical="15dp"
android:layout_weight="1" android:layout_weight="1"
android:orientation="vertical"> android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
...@@ -102,7 +104,8 @@ ...@@ -102,7 +104,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginVertical="15dp" android:layout_marginVertical="15dp"
android:layout_weight="1" android:layout_weight="1"
android:orientation="vertical"> android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
......
<?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="360dp"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="36dp"
android:src="@mipmap/delicon"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
android:gravity="center"
android:text="Delete the files?"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginHorizontal="30dp"
android:layout_marginTop="14dp"
android:gravity="center"
android:textColor="#666666"
android:textSize="14sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_delete"
android:layout_width="250dp"
android:layout_height="44dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="24dp"
android:background="@drawable/bg_577dfd_22"
android:gravity="center"
android:text="Delete"
android:textColor="@color/white"
android:textSize="17sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:layout_marginBottom="25dp"
android:text="Cancel"
android:textColor="#666666"
android:textSize="17sp"
tools:ignore="HardcodedText" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<dimen name="dp_8">8dp</dimen> <dimen name="dp_8">8dp</dimen>
<dimen name="dp_300">300dp</dimen>
</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