Add ignore battery optimizations card

This commit is contained in:
世界 2023-07-16 13:29:55 +08:00
parent f9fef233ca
commit 948312e9e4
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
6 changed files with 269 additions and 169 deletions

View file

@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"

View file

@ -4,6 +4,7 @@ import android.app.Application
import android.app.NotificationManager
import android.content.Context
import android.net.ConnectivityManager
import android.os.PowerManager
import androidx.core.content.getSystemService
import go.Seq
import io.nekohasekai.sfa.bg.UpdateProfileWork
@ -35,6 +36,7 @@ class Application : Application() {
val notification by lazy { application.getSystemService<NotificationManager>()!! }
val connectivity by lazy { application.getSystemService<ConnectivityManager>()!! }
val packageManager by lazy { application.packageManager }
val powerManager by lazy { application.getSystemService<PowerManager>()!! }
}
}

View file

@ -268,7 +268,8 @@ class DashboardFragment : Fragment(), CommandClientHandler {
return
}
runCatching {
Libbox.newStandaloneCommandClient(mainActivity.filesDir.absolutePath).serviceReload()
Libbox.newStandaloneCommandClient(mainActivity.filesDir.absolutePath)
.serviceReload()
}.onFailure {
withContext(Dispatchers.Main) {
mainActivity.errorDialogBuilder(it).show()

View file

@ -1,14 +1,19 @@
package io.nekohasekai.sfa.ui.main
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isGone
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.microsoft.appcenter.AppCenter
import com.microsoft.appcenter.distribute.Distribute
import io.nekohasekai.libbox.Libbox
import io.nekohasekai.sfa.Application
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.constant.EnabledType
import io.nekohasekai.sfa.database.Settings
@ -35,6 +40,14 @@ class SettingsFragment : Fragment() {
return binding.root
}
private val requestIgnoreBatteryOptimizations = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { _ ->
lifecycleScope.launch(Dispatchers.IO) {
reloadSettings()
}
}
private fun onCreate() {
val activity = activity as MainActivity? ?: return
binding.versionText.text = Libbox.version()
@ -80,6 +93,17 @@ class SettingsFragment : Fragment() {
Settings.disableMemoryLimit = !newValue
}
}
binding.dontKillMyAppButton.setOnClickListener {
it.context.launchCustomTab("https://dontkillmyapp.com/")
}
binding.requestIgnoreBatteryOptimizationsButton.setOnClickListener {
requestIgnoreBatteryOptimizations.launch(
Intent(
android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
Uri.parse("package:${Application.application.packageName}")
)
)
}
binding.communityButton.setOnClickListener {
it.context.launchCustomTab("https://community.sagernet.org/")
}
@ -96,6 +120,8 @@ class SettingsFragment : Fragment() {
)
val appCenterEnabled = Settings.analyticsAllowed == Settings.ANALYSIS_ALLOWED
val checkUpdateEnabled = Settings.checkUpdateEnabled
val removeBackgroudPermissionPage =
Application.powerManager.isIgnoringBatteryOptimizations(Application.application.packageName)
withContext(Dispatchers.Main) {
binding.dataSizeText.text = dataSize
binding.appCenterEnabled.text = EnabledType.from(appCenterEnabled).name
@ -105,6 +131,7 @@ class SettingsFragment : Fragment() {
binding.checkUpdateEnabled.setSimpleItems(R.array.enabled)
binding.disableMemoryLimit.text = EnabledType.from(!Settings.disableMemoryLimit).name
binding.disableMemoryLimit.setSimpleItems(R.array.enabled)
binding.backgroundPermissionCard.isGone = removeBackgroudPermissionPage
}
}

View file

@ -1,229 +1,294 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<ScrollView 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:orientation="vertical"
android:padding="16dp">
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/appCenterCard"
style="?attr/materialCardViewElevatedStyle"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<LinearLayout
<com.google.android.material.card.MaterialCardView
android:id="@+id/appCenterCard"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_app_center"
android:textAppearance="?attr/textAppearanceTitleLarge" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/appCenterEnabled"
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="@string/enabled">
android:orientation="vertical"
android:padding="16dp">
<AutoCompleteTextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_app_center"
android:textAppearance="?attr/textAppearanceTitleLarge" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/appCenterEnabled"
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:text="@string/disabled"
app:simpleItems="@array/enabled" />
android:layout_marginTop="16dp"
android:hint="@string/enabled">
</com.google.android.material.textfield.TextInputLayout>
<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:text="@string/disabled"
app:simpleItems="@array/enabled" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/checkUpdateEnabled"
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/check_update">
</com.google.android.material.textfield.TextInputLayout>
<AutoCompleteTextView
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/checkUpdateEnabled"
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:text="@string/disabled"
app:simpleItems="@array/enabled" />
android:layout_marginTop="8dp"
android:hint="@string/check_update">
</com.google.android.material.textfield.TextInputLayout>
<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:text="@string/disabled"
app:simpleItems="@array/enabled" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/statusCard"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
<com.google.android.material.card.MaterialCardView
android:id="@+id/statusCard"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
android:layout_marginTop="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/core"
android:textAppearance="?attr/textAppearanceTitleLarge">
</TextView>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/disableMemoryLimit"
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/memory_limit">
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
<AutoCompleteTextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/core"
android:textAppearance="?attr/textAppearanceTitleLarge">
</TextView>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/disableMemoryLimit"
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:text="@string/enabled"
app:simpleItems="@array/enabled" />
android:layout_marginTop="8dp"
android:hint="@string/memory_limit">
</com.google.android.material.textfield.TextInputLayout>
<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:text="@string/enabled"
app:simpleItems="@array/enabled" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
</com.google.android.material.textfield.TextInputLayout>
<TextView
style="?attr/textAppearanceTitleSmall"
android:layout_width="0dp"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/core_version" />
android:layout_marginTop="16dp">
<TextView
android:id="@+id/versionText"
style="?attr/textAppearanceBodyMedium"
android:layout_width="wrap_content"
<TextView
style="?attr/textAppearanceTitleSmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/core_version" />
<TextView
android:id="@+id/versionText"
style="?attr/textAppearanceBodyMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
tools:text="@string/loading" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
style="?attr/textAppearanceTitleSmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/core_data_size" />
<TextView
android:id="@+id/dataSizeText"
style="?attr/textAppearanceBodyMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/loading" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
tools:text="@string/loading" />
android:layout_marginTop="8dp"
android:gravity="center_vertical|end"
android:orientation="horizontal">
<Button
android:id="@+id/clearButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_clear_working_directory"
android:textColor="#E91E63" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
style="?attr/textAppearanceTitleSmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/core_data_size" />
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/dataSizeText"
style="?attr/textAppearanceBodyMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/loading" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical|end"
android:orientation="horizontal">
<Button
android:id="@+id/clearButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_clear_working_directory"
android:textColor="#E91E63" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/aboutCard"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<LinearLayout
<com.google.android.material.card.MaterialCardView
android:id="@+id/backgroundPermissionCard"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
android:layout_marginTop="16dp"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_title"
android:textAppearance="?attr/textAppearanceTitleLarge">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/app_description" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|end"
android:orientation="horizontal">
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
<Button
android:id="@+id/documentationButton"
style="@style/Widget.Material3.Button.TextButton"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/documentation_button" />
android:text="@string/background_permission"
android:textAppearance="?attr/textAppearanceTitleLarge">
<Button
android:id="@+id/communityButton"
style="@style/Widget.Material3.Button.TextButton"
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/community_button" />
android:layout_marginTop="8dp"
android:text="@string/background_permission_description" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|end"
android:orientation="horizontal">
<Button
android:id="@+id/dontKillMyAppButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/read_more" />
<Button
android:id="@+id/requestIgnoreBatteryOptimizationsButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/request_background_permission" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/aboutCard"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_title"
android:textAppearance="?attr/textAppearanceTitleLarge">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/app_description" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|end"
android:orientation="horizontal">
<Button
android:id="@+id/documentationButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/documentation_button" />
<Button
android:id="@+id/communityButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/community_button" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>

View file

@ -80,5 +80,9 @@
<string name="documentation_button">Documentation</string>
<string name="community_button">Community</string>
<string name="memory_limit">Memory Limit</string>
<string name="background_permission">Background permission</string>
<string name="background_permission_description">Apply for the necessary permissions in order for the VPN to function properly.\n\nIf you are using a device made by a Chinese company, the card may not disappear after the permission is granted.</string>
<string name="read_more">Read More</string>
<string name="request_background_permission">Ignore battery optimizations</string>
</resources>