add dialog to disable battery optimization. WIP

this is just a quick&dirty approach for testing...

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2022-05-31 15:06:17 +02:00
parent 8560728546
commit bad57b92cb
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
4 changed files with 113 additions and 31 deletions

View File

@ -52,8 +52,8 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_PROFILE" /> <uses-permission android:name="android.permission.READ_PROFILE" />
@ -79,6 +79,8 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application <application
android:name=".application.NextcloudTalkApplication" android:name=".application.NextcloudTalkApplication"
android:allowBackup="true" android:allowBackup="true"
@ -87,9 +89,9 @@
android:label="@string/nc_app_name" android:label="@string/nc_app_name"
android:largeHeap="true" android:largeHeap="true"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme.Launcher" android:theme="@style/AppTheme.Launcher"
android:requestLegacyExternalStorage="true"
tools:ignore="UnusedAttribute" tools:ignore="UnusedAttribute"
tools:replace="label, icon, theme, name, allowBackup"> tools:replace="label, icon, theme, name, allowBackup">
@ -127,41 +129,38 @@
<activity <activity
android:name=".activities.CallActivity" android:name=".activities.CallActivity"
android:theme="@style/AppTheme.CallLauncher"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:launchMode="singleTask"
android:taskAffinity=".call"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:showOnLockScreen="true"/> android:launchMode="singleTask"
android:showOnLockScreen="true"
android:supportsPictureInPicture="true"
android:taskAffinity=".call"
android:theme="@style/AppTheme.CallLauncher" />
<activity <activity
android:name=".activities.CallNotificationActivity" android:name=".activities.CallNotificationActivity"
android:theme="@style/AppTheme.CallLauncher"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:launchMode="singleTask"
android:taskAffinity=".call"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:showOnLockScreen="true" /> android:launchMode="singleTask"
android:showOnLockScreen="true"
android:supportsPictureInPicture="true"
android:taskAffinity=".call"
android:theme="@style/AppTheme.CallLauncher" />
<activity <activity
android:name=".activities.FullScreenImageActivity" android:name=".activities.FullScreenImageActivity"
android:theme="@style/FullScreenImageTheme" android:configChanges="orientation|keyboardHidden|screenSize"
android:configChanges="orientation|keyboardHidden|screenSize"> android:theme="@style/FullScreenImageTheme"></activity>
</activity>
<activity <activity
android:name=".activities.FullScreenMediaActivity" android:name=".activities.FullScreenMediaActivity"
android:theme="@style/FullScreenMediaTheme" android:configChanges="orientation|keyboardHidden|screenSize"
android:configChanges="orientation|keyboardHidden|screenSize"> android:theme="@style/FullScreenMediaTheme"></activity>
</activity>
<activity <activity
android:name=".activities.FullScreenTextViewerActivity" android:name=".activities.FullScreenTextViewerActivity"
android:theme="@style/FullScreenTextTheme" android:configChanges="orientation|keyboardHidden|screenSize"
android:configChanges="orientation|keyboardHidden|screenSize"> android:theme="@style/FullScreenTextTheme"></activity>
</activity>
<activity <activity
android:name=".activities.TakePhotoActivity" android:name=".activities.TakePhotoActivity"
@ -170,7 +169,7 @@
<activity <activity
android:name=".shareditems.activities.SharedItemsActivity" android:name=".shareditems.activities.SharedItemsActivity"
android:theme="@style/AppTheme"/> android:theme="@style/AppTheme" />
<receiver android:name=".receivers.PackageReplacedReceiver"> <receiver android:name=".receivers.PackageReplacedReceiver">
<intent-filter> <intent-filter>

View File

@ -93,6 +93,7 @@ import com.nextcloud.talk.utils.DisplayUtils;
import com.nextcloud.talk.utils.UriUtils; import com.nextcloud.talk.utils.UriUtils;
import com.nextcloud.talk.utils.bundle.BundleKeys; import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils; import com.nextcloud.talk.utils.database.user.UserUtils;
import com.nextcloud.talk.utils.power.PowerManagerUtil;
import com.nextcloud.talk.utils.preferences.AppPreferences; import com.nextcloud.talk.utils.preferences.AppPreferences;
import com.webianks.library.PopupBubble; import com.webianks.library.PopupBubble;
import com.yarolegovich.lovelydialog.LovelySaveStateHandler; import com.yarolegovich.lovelydialog.LovelySaveStateHandler;
@ -253,6 +254,10 @@ public class ConversationsListController extends BaseController implements Searc
adapter.addListener(this); adapter.addListener(this);
prepareViews(); prepareViews();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
new PowerManagerUtil().askForBatteryOptimization(getActivity());
}
} }
private void loadUserAvatar(MaterialButton button) { private void loadUserAvatar(MaterialButton button) {
@ -427,8 +432,8 @@ public class ConversationsListController extends BaseController implements Searc
MainActivity activity = (MainActivity) getActivity(); MainActivity activity = (MainActivity) getActivity();
if (activity != null) { if (activity != null) {
activity.binding.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator( activity.binding.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(
activity.binding.appBar.getContext(), activity.binding.appBar.getContext(),
R.animator.appbar_elevation_off) R.animator.appbar_elevation_off)
); );
activity.binding.toolbar.setVisibility(View.GONE); activity.binding.toolbar.setVisibility(View.GONE);
activity.binding.searchToolbar.setVisibility(View.VISIBLE); activity.binding.searchToolbar.setVisibility(View.VISIBLE);
@ -644,8 +649,8 @@ public class ConversationsListController extends BaseController implements Searc
List<AbstractFlexibleItem> openConversationItems = new ArrayList<>(); List<AbstractFlexibleItem> openConversationItems = new ArrayList<>();
openConversationsQueryDisposable = ncApi.getOpenConversations( openConversationsQueryDisposable = ncApi.getOpenConversations(
credentials, credentials,
ApiUtils.getUrlForOpenConversations(apiVersion, currentUser.getBaseUrl())) ApiUtils.getUrlForOpenConversations(apiVersion, currentUser.getBaseUrl()))
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(roomsOverall -> { .subscribe(roomsOverall -> {
@ -690,7 +695,7 @@ public class ConversationsListController extends BaseController implements Searc
if (getParentController() != null && getParentController().getRouter() != null) { if (getParentController() != null && getParentController().getRouter() != null) {
Log.d(TAG, "Starting reauth webview via getParentController()"); Log.d(TAG, "Starting reauth webview via getParentController()");
getParentController().getRouter().pushController((RouterTransaction.with getParentController().getRouter().pushController((RouterTransaction.with
(new WebViewLoginController(currentUser.getBaseUrl(), true)) (new WebViewLoginController(currentUser.getBaseUrl(), true))
.pushChangeHandler(new VerticalChangeHandler()) .pushChangeHandler(new VerticalChangeHandler())
.popChangeHandler(new VerticalChangeHandler()))); .popChangeHandler(new VerticalChangeHandler())));
} else { } else {
@ -1178,7 +1183,7 @@ public class ConversationsListController extends BaseController implements Searc
onAttach(getView()); onAttach(getView());
} else if (!otherUserExists) { } else if (!otherUserExists) {
getRouter().setRoot(RouterTransaction.with( getRouter().setRoot(RouterTransaction.with(
new ServerSelectionController()) new ServerSelectionController())
.pushChangeHandler(new VerticalChangeHandler()) .pushChangeHandler(new VerticalChangeHandler())
.popChangeHandler(new VerticalChangeHandler())); .popChangeHandler(new VerticalChangeHandler()));
} }
@ -1188,7 +1193,7 @@ public class ConversationsListController extends BaseController implements Searc
@Override @Override
public void onClick(View v) { public void onClick(View v) {
getRouter().pushController(RouterTransaction.with( getRouter().pushController(RouterTransaction.with(
new WebViewLoginController(currentUser.getBaseUrl(), true)) new WebViewLoginController(currentUser.getBaseUrl(), true))
.pushChangeHandler(new VerticalChangeHandler()) .pushChangeHandler(new VerticalChangeHandler())
.popChangeHandler(new VerticalChangeHandler())); .popChangeHandler(new VerticalChangeHandler()));
} }
@ -1221,7 +1226,7 @@ public class ConversationsListController extends BaseController implements Searc
onAttach(getView()); onAttach(getView());
} else if (!otherUserExists) { } else if (!otherUserExists) {
getRouter().setRoot(RouterTransaction.with( getRouter().setRoot(RouterTransaction.with(
new ServerSelectionController()) new ServerSelectionController())
.pushChangeHandler(new VerticalChangeHandler()) .pushChangeHandler(new VerticalChangeHandler())
.popChangeHandler(new VerticalChangeHandler())); .popChangeHandler(new VerticalChangeHandler()));
} }

View File

@ -0,0 +1,57 @@
package com.nextcloud.talk.utils.power
import android.annotation.SuppressLint
import android.content.Context
import android.content.Context.POWER_SERVICE
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.LifecycleObserver
import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R
class PowerManagerUtil : LifecycleObserver {
@RequiresApi(Build.VERSION_CODES.M)
fun askForBatteryOptimization(context: Context) {
if (checkIfBatteryOptimizationEnabled(context)) {
val alertDialogBuilder = AlertDialog.Builder(context, R.style.Theme_ownCloud_Dialog)
.setTitle("Battery optimization")
.setMessage(
"Your device may have battery optimization enabled. Notifications work only properly if " +
"you exclude this app from it."
)
.setPositiveButton("disable") { _, _ ->
@SuppressLint("BatteryLife") val intent = Intent(
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
Uri.parse("package:" + BuildConfig.APPLICATION_ID)
)
context.startActivity(intent)
}
.setNeutralButton("close") { dialog, _ -> dialog.dismiss() }
alertDialogBuilder.show()
}
}
/**
* Check if battery optimization is enabled. If unknown, fallback to true.
*
* @return true if battery optimization is enabled
*/
@RequiresApi(Build.VERSION_CODES.M)
private fun checkIfBatteryOptimizationEnabled(context: Context): Boolean {
val powerManager = context.getSystemService(POWER_SERVICE) as PowerManager?
return when {
powerManager != null -> !powerManager.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID)
else -> true
}
}
companion object {
private val TAG = PowerManagerUtil::class.simpleName
}
}

View File

@ -122,6 +122,27 @@
<item name="iconTint">@color/fontAppbar</item> <item name="iconTint">@color/fontAppbar</item>
</style> </style>
<!-- Dialogs -->
<style name="Theme.ownCloud.Dialog" parent="@style/Theme.MaterialComponents.DayNight.Dialog.Alert">
<item name="windowNoTitle">false</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowBackground">@color/bg_default</item>
<item name="android:textAllCaps">false</item>
<item name="textInputStyle">@style/Widget.App.TextInputLayout</item>
</style>
<style name="Widget.App.TextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.TextInputLayout</item>
<item name="hintTextColor">?attr/colorOnSurface</item>
</style>
<style name="ThemeOverlay.App.TextInputLayout" parent="ThemeOverlay.MaterialComponents.TextInputEditText.OutlinedBox">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorOnSurface">@color/colorPrimary</item>
<item name="colorError">@color/hwSecurityRed</item>
<item name="editTextStyle">@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox</item>
</style>
<style name="menuTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Menu"> <style name="menuTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Menu">
<item name="android:textAllCaps">false</item> <item name="android:textAllCaps">false</item>
</style> </style>