Skip to content

Commit e683c4b

Browse files
committed
fix: battery optimization check
Signed-off-by: alperozturk <[email protected]>
1 parent c49412b commit e683c4b

File tree

2 files changed

+75
-41
lines changed

2 files changed

+75
-41
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2025 Alper Ozturk <[email protected]>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.nextcloud.utils
9+
10+
import android.annotation.SuppressLint
11+
import android.content.Context
12+
import android.content.Intent
13+
import android.os.PowerManager
14+
import android.provider.Settings
15+
import androidx.core.net.toUri
16+
import com.owncloud.android.lib.common.utils.Log_OC
17+
18+
object BatteryOptimizationHelper {
19+
20+
private const val TAG = "BatteryOptimizationHelper"
21+
22+
fun isBatteryOptimizationEnabled(context: Context): Boolean {
23+
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
24+
return !pm.isIgnoringBatteryOptimizations(context.packageName)
25+
}
26+
27+
@Suppress("TooGenericExceptionCaught")
28+
@SuppressLint("BatteryLife")
29+
fun openBatteryOptimizationSettings(context: Context) {
30+
try {
31+
val intent = Intent(
32+
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
33+
"package:${context.packageName}".toUri()
34+
)
35+
36+
if (intent.resolveActivity(context.packageManager) != null) {
37+
context.startActivity(intent)
38+
} else {
39+
// Fallback to generic battery optimization settings
40+
context.startActivity(Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS))
41+
}
42+
} catch (e: Exception) {
43+
Log_OC.d(TAG, "open battery optimization settings: ", e)
44+
}
45+
}
46+
}

app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,12 @@ import android.content.Intent
1414
import android.content.pm.PackageManager
1515
import android.os.Bundle
1616
import android.os.Looper
17-
import android.os.PowerManager
18-
import android.provider.Settings
1917
import android.text.TextUtils
2018
import android.view.Menu
2119
import android.view.MenuItem
2220
import android.view.View
2321
import androidx.annotation.VisibleForTesting
2422
import androidx.appcompat.app.AlertDialog
25-
import androidx.core.net.toUri
2623
import androidx.drawerlayout.widget.DrawerLayout
2724
import androidx.lifecycle.Lifecycle
2825
import androidx.lifecycle.lifecycleScope
@@ -36,10 +33,10 @@ import com.nextcloud.client.jobs.MediaFoldersDetectionWork
3633
import com.nextcloud.client.jobs.NotificationWork
3734
import com.nextcloud.client.jobs.upload.FileUploadWorker
3835
import com.nextcloud.client.preferences.SubFolderRule
36+
import com.nextcloud.utils.BatteryOptimizationHelper
3937
import com.nextcloud.utils.extensions.getParcelableArgument
4038
import com.nextcloud.utils.extensions.isDialogFragmentReady
4139
import com.nextcloud.utils.extensions.setVisibleIf
42-
import com.owncloud.android.BuildConfig
4340
import com.owncloud.android.MainApp
4441
import com.owncloud.android.R
4542
import com.owncloud.android.databinding.StoragePermissionWarningBannerBinding
@@ -576,7 +573,7 @@ class SyncedFoldersActivity :
576573
}
577574
if (syncedFolderDisplayItem.isEnabled) {
578575
backgroundJobManager.startAutoUploadImmediately(syncedFolderDisplayItem, overridePowerSaving = false)
579-
showBatteryOptimizationInfo()
576+
showBatteryOptimizationDialogIfNeeded()
580577
}
581578
}
582579

@@ -710,7 +707,7 @@ class SyncedFoldersActivity :
710707
}
711708
dialogFragment = null
712709
if (syncedFolder.isEnabled) {
713-
showBatteryOptimizationInfo()
710+
showBatteryOptimizationDialogIfNeeded()
714711
}
715712
}
716713

@@ -834,44 +831,35 @@ class SyncedFoldersActivity :
834831
}
835832
}
836833

837-
private fun showBatteryOptimizationInfo() {
838-
if (checkIfBatteryOptimizationEnabled()) {
839-
val alertDialogBuilder = MaterialAlertDialogBuilder(this, R.style.Theme_ownCloud_Dialog)
840-
.setTitle(getString(R.string.battery_optimization_title))
841-
.setMessage(getString(R.string.battery_optimization_message))
842-
.setPositiveButton(getString(R.string.battery_optimization_disable)) { _, _ ->
843-
// show instant upload
844-
@SuppressLint("BatteryLife")
845-
val intent = Intent(
846-
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
847-
("package:" + BuildConfig.APPLICATION_ID).toUri()
848-
)
849-
if (intent.resolveActivity(packageManager) != null) {
850-
startActivity(intent)
851-
}
852-
}
853-
.setNeutralButton(getString(R.string.battery_optimization_close)) { dialog, _ -> dialog.dismiss() }
854-
.setIcon(R.drawable.ic_battery_alert)
855-
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
856-
val alertDialog = alertDialogBuilder.show()
857-
viewThemeUtils.platform.colorTextButtons(
858-
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE),
859-
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL)
860-
)
861-
}
834+
private fun showBatteryOptimizationDialogIfNeeded() {
835+
if (!BatteryOptimizationHelper.isBatteryOptimizationEnabled(this)) {
836+
Log_OC.d(TAG, "battery optimization is disabled")
837+
return
862838
}
839+
840+
showBatteryOptimizationDialog()
863841
}
864842

865-
/**
866-
* Check if battery optimization is enabled. If unknown, fallback to true.
867-
*
868-
* @return true if battery optimization is enabled
869-
*/
870-
private fun checkIfBatteryOptimizationEnabled(): Boolean {
871-
val powerManager = getSystemService(POWER_SERVICE) as PowerManager?
872-
return when {
873-
powerManager != null -> !powerManager.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID)
874-
else -> !appInfo.isDebugBuild
843+
private fun showBatteryOptimizationDialog() {
844+
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
845+
Log_OC.w(TAG, "Activity not resumed, skipping battery dialog")
846+
return
875847
}
848+
849+
val dialog = MaterialAlertDialogBuilder(this, R.style.Theme_ownCloud_Dialog)
850+
.setTitle(R.string.battery_optimization_title)
851+
.setMessage(R.string.battery_optimization_message)
852+
.setPositiveButton(R.string.battery_optimization_disable) { _, _ ->
853+
BatteryOptimizationHelper.openBatteryOptimizationSettings(this)
854+
}
855+
.setNeutralButton(R.string.battery_optimization_close, null)
856+
.setIcon(R.drawable.ic_battery_alert)
857+
858+
val alertDialog = dialog.show()
859+
860+
viewThemeUtils.platform.colorTextButtons(
861+
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE),
862+
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL)
863+
)
876864
}
877865
}

0 commit comments

Comments
 (0)