mirror of
https://github.com/YTVanced/VancedManager
synced 2024-11-10 12:55:06 +00:00
added sleep timer adjuster and optimized views
This commit is contained in:
parent
2a5e46855c
commit
1f9ecfddc0
11 changed files with 213 additions and 38 deletions
|
@ -16,10 +16,5 @@ class ThemedMaterialCheckbox @JvmOverloads constructor(
|
|||
) : MaterialCheckBox(context, attributeSet, R.attr.checkboxStyle) {
|
||||
init {
|
||||
buttonTintList = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
|
||||
context.lifecycleOwner()?.let { owner ->
|
||||
accentColor.observe(owner) { color ->
|
||||
buttonTintList = ColorStateList.valueOf(color.toInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,10 +16,5 @@ class ThemedMaterialRadioButton @JvmOverloads constructor(
|
|||
) : MaterialRadioButton(context, attributeSet, R.attr.radioButtonStyle) {
|
||||
init {
|
||||
buttonTintList = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
|
||||
context.lifecycleOwner()?.let { owner ->
|
||||
accentColor.observe(owner) { color ->
|
||||
buttonTintList = ColorStateList.valueOf(color.toInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.vanced.manager.ui.core
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.utils.Extensions.getDefaultPrefs
|
||||
import com.vanced.manager.utils.ThemeHelper.defAccentColor
|
||||
|
||||
class ThemedSwipeRefreshlayout @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attributeSet: AttributeSet? = null
|
||||
) : SwipeRefreshLayout(context, attributeSet) {
|
||||
init {
|
||||
setColorSchemeColors(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
|
||||
initAttrs(context, attributeSet)
|
||||
}
|
||||
private fun initAttrs(context: Context, attributeSet: AttributeSet?) {
|
||||
attributeSet.let {
|
||||
val typedAttrs = context.obtainStyledAttributes(it, R.styleable.ThemedSwipeRefreshlayout, 0, 0)
|
||||
setProgressBackgroundColorSchemeColor(typedAttrs.getColor(R.styleable.ThemedSwipeRefreshlayout_progressBackgroundColor, 0))
|
||||
typedAttrs.recycle()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.vanced.manager.ui.dialogs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.edit
|
||||
import com.vanced.manager.core.ui.base.BindingDialogFragment
|
||||
import com.vanced.manager.databinding.DialogServicedTimerBinding
|
||||
import com.vanced.manager.utils.Extensions.getDefaultPrefs
|
||||
import com.vanced.manager.utils.Extensions.writeServiceDScript
|
||||
import com.vanced.manager.utils.PackageHelper
|
||||
import com.vanced.manager.utils.PackageHelper.getPackageDir
|
||||
import com.vanced.manager.utils.PackageHelper.getPkgNameRoot
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
class ServiceDTimerDialog : BindingDialogFragment<DialogServicedTimerBinding>() {
|
||||
|
||||
private val prefs by lazy { requireActivity().getDefaultPrefs() }
|
||||
|
||||
override fun binding(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): DialogServicedTimerBinding = DialogServicedTimerBinding.inflate(inflater, container, false)
|
||||
|
||||
override fun otherSetups() {
|
||||
bindData()
|
||||
}
|
||||
|
||||
private fun bindData() {
|
||||
with (binding) {
|
||||
servicedSlider.value = prefs.getInt("serviced_sleep_timer", 1).toFloat()
|
||||
servicedCancel.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
servicedSave.setOnClickListener {
|
||||
try {
|
||||
arrayOf("vanced", "music").forEach { app ->
|
||||
val apkFPath = "${PackageHelper.apkInstallPath}/${app.capitalize(Locale.ROOT)}/base.apk"
|
||||
getPackageDir(requireActivity(), getPkgNameRoot(app))?.let { it1 -> requireActivity().writeServiceDScript(apkFPath, it1, app) }
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
prefs.edit {
|
||||
putInt("serviced_sleep_timer", servicedSlider.value.toInt())
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
package com.vanced.manager.ui.fragments
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
|
@ -26,12 +28,20 @@ import java.io.File
|
|||
class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
|
||||
|
||||
private companion object {
|
||||
|
||||
const val LIGHT = "Light"
|
||||
const val DARK = "Dark"
|
||||
}
|
||||
|
||||
private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) }
|
||||
private val listener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
|
||||
when (key) {
|
||||
"serviced_sleep_timer" -> {
|
||||
binding.servicedTimer.setSummary(sharedPreferences.getInt(key, 1).toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var variant: String
|
||||
|
||||
override fun binding(
|
||||
inflater: LayoutInflater,
|
||||
|
@ -41,14 +51,22 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
|
|||
|
||||
override fun otherSetups() {
|
||||
setHasOptionsMenu(true)
|
||||
prefs.registerOnSharedPreferenceChangeListener(listener)
|
||||
bindData()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
prefs.unregisterOnSharedPreferenceChangeListener(listener)
|
||||
}
|
||||
|
||||
private fun bindData() {
|
||||
with(binding) {
|
||||
variant = prefs.getString("vanced_variant", "nonroot").toString()
|
||||
bindRecycler()
|
||||
bindFirebase()
|
||||
bindManagerVariant()
|
||||
bindServiceDTimer()
|
||||
bindClearFiles()
|
||||
bindManagerTheme()
|
||||
bindManagerAccentColor()
|
||||
|
@ -74,10 +92,19 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
|
|||
|
||||
private fun FragmentSettingsBinding.bindManagerVariant() {
|
||||
managerVariant.apply {
|
||||
prefs.getString("vanced_variant", "nonroot")?.let { setSummary(it) }
|
||||
setSummary(variant)
|
||||
setOnClickListener { showDialog(ManagerVariantDialog()) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun FragmentSettingsBinding.bindServiceDTimer() {
|
||||
servicedTimer.apply {
|
||||
if (variant == "root") this.isVisible = true
|
||||
setSummary(prefs.getInt("serviced_sleep_timer", 1).toString())
|
||||
setOnClickListener { showDialog(ServiceDTimerDialog()) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun FragmentSettingsBinding.bindClearFiles() {
|
||||
clearFiles.setOnClickListener {
|
||||
with(requireActivity()) {
|
||||
|
@ -104,11 +131,11 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
|
|||
}
|
||||
|
||||
private fun FragmentSettingsBinding.bindManagerAccentColor() {
|
||||
managerAccentColor.setSummary(prefs.getInt("manager_accent_color", defAccentColor).toHex())
|
||||
managerAccentColor.apply{
|
||||
setSummary(prefs.getInt("manager_accent_color", defAccentColor).toHex())
|
||||
setOnClickListener { showDialog(ManagerAccentColorDialog()) }
|
||||
accentColor.observe(viewLifecycleOwner) {
|
||||
managerAccentColor.setSummary(prefs.getInt("manager_accent_color", defAccentColor).toHex())
|
||||
setSummary(it.toHex())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import androidx.preference.PreferenceManager.getDefaultSharedPreferences
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.radiobutton.MaterialRadioButton
|
||||
import com.topjohnwu.superuser.io.SuFile
|
||||
import com.topjohnwu.superuser.io.SuFileOutputStream
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.utils.InternetTools.baseUrl
|
||||
import com.vanced.manager.utils.ThemeHelper.accentColor
|
||||
|
@ -86,4 +88,11 @@ object Extensions {
|
|||
}
|
||||
}
|
||||
|
||||
fun Context.writeServiceDScript(path: String, apkFPath: String, app: String) {
|
||||
val shellFileZ = SuFile.open("/data/adb/service.d/$app.sh")
|
||||
shellFileZ.createNewFile()
|
||||
val code = """#!/system/bin/sh${"\n"}while [ "`getprop sys.boot_completed | tr -d '\r' `" != "1" ]; do sleep ${getDefaultPrefs().getInt("serviced_sleep_timer", 1)}; done${"\n"}mount -o bind $apkFPath $path"""
|
||||
SuFileOutputStream(shellFileZ).use { out -> out.write(code.toByteArray())}
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,6 @@ import android.os.Build
|
|||
import android.util.Log
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import com.topjohnwu.superuser.io.SuFile
|
||||
import com.topjohnwu.superuser.io.SuFileOutputStream
|
||||
import com.vanced.manager.BuildConfig
|
||||
import com.vanced.manager.core.installer.AppInstallerService
|
||||
import com.vanced.manager.core.installer.AppUninstallerService
|
||||
|
@ -19,6 +18,7 @@ import com.vanced.manager.utils.AppUtils.sendCloseDialog
|
|||
import com.vanced.manager.utils.AppUtils.sendFailure
|
||||
import com.vanced.manager.utils.AppUtils.sendRefresh
|
||||
import com.vanced.manager.utils.AppUtils.vancedRootPkg
|
||||
import com.vanced.manager.utils.Extensions.writeServiceDScript
|
||||
import com.vanced.manager.utils.InternetTools.music
|
||||
import com.vanced.manager.utils.InternetTools.vanced
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
@ -33,7 +33,7 @@ import kotlin.collections.HashMap
|
|||
|
||||
object PackageHelper {
|
||||
|
||||
private const val apkInstallPath = "/data/adb"
|
||||
const val apkInstallPath = "/data/adb"
|
||||
private val vancedThemes = arrayOf("black", "dark", "pink", "blue")
|
||||
|
||||
init {
|
||||
|
@ -45,7 +45,7 @@ object PackageHelper {
|
|||
)
|
||||
}
|
||||
|
||||
private fun getAppName(pkg: String): String {
|
||||
private fun getAppNameRoot(pkg: String): String {
|
||||
return when (pkg) {
|
||||
vancedRootPkg -> "vanced"
|
||||
musicRootPkg -> "music"
|
||||
|
@ -53,6 +53,13 @@ object PackageHelper {
|
|||
}
|
||||
}
|
||||
|
||||
fun getPkgNameRoot(app: String): String {
|
||||
return when (app) {
|
||||
"vanced" -> vancedRootPkg
|
||||
"music" -> musicRootPkg
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
fun isPackageInstalled(packageName: String, packageManager: PackageManager): Boolean {
|
||||
return try {
|
||||
packageManager.getPackageInfo(packageName, 0)
|
||||
|
@ -127,7 +134,7 @@ object PackageHelper {
|
|||
}
|
||||
|
||||
fun uninstallRootApk(pkg: String): Boolean {
|
||||
val app = getAppName(pkg)
|
||||
val app = getAppNameRoot(pkg)
|
||||
Shell.su("rm -rf $apkInstallPath/${app.capitalize(Locale.ROOT)}").exec()
|
||||
Shell.su("rm $apkInstallPath/post-fs-data.d/$app.sh").exec()
|
||||
Shell.su("rm $apkInstallPath/service.d/$app.sh").exec()
|
||||
|
@ -432,7 +439,7 @@ object PackageHelper {
|
|||
val apkFPath = "$apkInstallPath/${app.capitalize(Locale.ROOT)}/base.apk"
|
||||
if (moveAPK(apath, apkFPath, pkg, context)) {
|
||||
if (chConV(apkFPath, context)) {
|
||||
if (setupScript(apkFPath, path, app, pkg)) {
|
||||
if (setupScript(apkFPath, path, app, pkg, context)) {
|
||||
return linkApp(apkFPath, pkg, path)
|
||||
}
|
||||
}
|
||||
|
@ -443,22 +450,15 @@ object PackageHelper {
|
|||
return false
|
||||
}
|
||||
|
||||
private fun setupScript(apkFPath: String, path: String, app: String, pkg: String): Boolean
|
||||
private fun setupScript(apkFPath: String, path: String, app: String, pkg: String, context: Context): Boolean
|
||||
{
|
||||
|
||||
val shellFileZ = SuFile.open("/data/adb/service.d/$app.sh")
|
||||
shellFileZ.createNewFile()
|
||||
|
||||
val code = """#!/system/bin/sh${"\n"}while [ "`getprop sys.boot_completed | tr -d '\r' `" != "1" ]; do sleep 1; done${"\n"}mount -o bind $apkFPath $path"""
|
||||
if (shellFileZ.exists()) {
|
||||
try {
|
||||
SuFileOutputStream(shellFileZ).use { out -> out.write(code.toByteArray())}
|
||||
context.writeServiceDScript(apkFPath, path, app)
|
||||
Shell.su("""echo "#!/system/bin/sh\nwhile read line; do echo \${"$"}{line} | grep $pkg | awk '{print \${'$'}2}' | xargs umount -l; done< /proc/mounts" > /data/adb/post-fs-data.d/$app.sh""").exec()
|
||||
return Shell.su("chmod 744 /data/adb/service.d/$app.sh").exec().isSuccess
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -603,7 +603,7 @@ object PackageHelper {
|
|||
}
|
||||
|
||||
//get path of the installed youtube
|
||||
private fun getPackageDir(context: Context, pkg: String): String?
|
||||
fun getPackageDir(context: Context, pkg: String): String?
|
||||
{
|
||||
val p = getPkgInfo(pkg, context)
|
||||
return if(p != null)
|
||||
|
|
50
app/src/main/res/layout/dialog_serviced_timer.xml
Normal file
50
app/src/main/res/layout/dialog_serviced_timer.xml
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView 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"
|
||||
tools:context=".ui.dialogs.AppDownloadDialog"
|
||||
style="@style/DialogCard">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/serviced_header"
|
||||
tools:text="Script Sleep Timer"
|
||||
style="@style/DialogCardTitle" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/serviced_slider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/serviced_header"
|
||||
android:layout_marginTop="24dp"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="50"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/serviced_slider"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<com.vanced.manager.ui.core.ThemedOutlinedMaterialButton
|
||||
android:id="@+id/serviced_cancel"
|
||||
android:layout_alignParentStart="true"
|
||||
android:textSize="15sp"
|
||||
android:text="@string/cancel"
|
||||
style="@style/OutlinedButtonStyle"/>
|
||||
|
||||
<com.vanced.manager.ui.core.ThemedMaterialButton
|
||||
android:id="@+id/serviced_save"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:text="@string/save"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
style="@style/ButtonStyle"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -1,9 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.vanced.manager.ui.core.ThemedSwipeRefreshlayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/home_refresh"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
app:progressBackgroundColor="?colorSurface">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
|
@ -58,5 +60,7 @@
|
|||
tools:itemCount="6"
|
||||
tools:listitem="@layout/view_social_link" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
</com.vanced.manager.ui.core.ThemedSwipeRefreshlayout>
|
||||
|
|
|
@ -49,11 +49,19 @@
|
|||
android:layout_height="wrap_content"
|
||||
app:preference_title="@string/variant" />
|
||||
|
||||
<com.vanced.manager.ui.core.EmptyPreference
|
||||
android:id="@+id/serviced_timer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:preference_title="Script Sleep Timer"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.vanced.manager.ui.core.EmptyPreference
|
||||
android:id="@+id/clearFiles"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:preference_title="@string/clear_files" />
|
||||
|
||||
</com.vanced.manager.ui.core.PreferenceCategory>
|
||||
|
||||
<com.vanced.manager.ui.core.PreferenceCategory
|
||||
|
@ -86,6 +94,9 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:preference_title="@string/select_apps" />
|
||||
|
||||
</com.vanced.manager.ui.core.PreferenceCategory>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
|
@ -32,4 +32,8 @@
|
|||
<attr name="preference_summary" format="reference|string"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="ThemedSwipeRefreshlayout">
|
||||
<attr name="progressBackgroundColor" format="reference|color" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
Loading…
Reference in a new issue