mirror of
https://github.com/breezy-weather/breezy-weather.git
synced 2025-12-07 13:50:05 +00:00
Drop support for Android Lollipop
This commit is contained in:
parent
89dd380c7a
commit
9e4a5fe2e5
22 changed files with 189 additions and 238 deletions
|
|
@ -19,7 +19,6 @@ package org.breezyweather.background.forecast
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.drawable.Icon
|
import android.graphics.drawable.Icon
|
||||||
import android.os.Build
|
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import breezyweather.domain.location.model.Location
|
import breezyweather.domain.location.model.Location
|
||||||
import breezyweather.domain.weather.model.Daily
|
import breezyweather.domain.weather.model.Daily
|
||||||
|
|
@ -130,9 +129,7 @@ class ForecastNotificationNotifier(
|
||||||
)
|
)
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
if (weather.current?.weatherCode != null) {
|
||||||
weather.current?.weatherCode != null
|
|
||||||
) {
|
|
||||||
try {
|
try {
|
||||||
notification.javaClass
|
notification.javaClass
|
||||||
.getMethod("setSmallIcon", Icon::class.java)
|
.getMethod("setSmallIcon", Icon::class.java)
|
||||||
|
|
@ -144,7 +141,7 @@ class ForecastNotificationNotifier(
|
||||||
daytime
|
daytime
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} catch (ignore: Exception) {
|
} catch (_: Exception) {
|
||||||
// do nothing.
|
// do nothing.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,13 +177,6 @@ class WeatherContentProvider : ContentProvider() {
|
||||||
selectionArgs: Array<String>?,
|
selectionArgs: Array<String>?,
|
||||||
sortOrder: String?,
|
sortOrder: String?,
|
||||||
): Cursor? {
|
): Cursor? {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
||||||
// Disable the content provider on SDK < 23 since it grants dangerous
|
|
||||||
// permissions at install-time
|
|
||||||
Log.w(TAG, "Content provider read is only available for SDK >= 23")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isAllowedPackage()) {
|
if (!isAllowedPackage()) {
|
||||||
Log.w(TAG, "Content provider is disabled for this app")
|
Log.w(TAG, "Content provider is disabled for this app")
|
||||||
return null
|
return null
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,10 @@ class AppUpdateChecker @Inject constructor(
|
||||||
forceCheck: Boolean = false,
|
forceCheck: Boolean = false,
|
||||||
): GetApplicationRelease.Result {
|
): GetApplicationRelease.Result {
|
||||||
// Disable app update checks for older Android versions that we're going to drop support for
|
// Disable app update checks for older Android versions that we're going to drop support for
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
/*if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||||
AppUpdateNotifier(context).promptOldAndroidVersion()
|
AppUpdateNotifier(context).promptOldAndroidVersion()
|
||||||
return GetApplicationRelease.Result.OsTooOld
|
return GetApplicationRelease.Result.OsTooOld
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val result = getApplicationRelease.await(
|
val result = getApplicationRelease.await(
|
||||||
|
|
|
||||||
|
|
@ -128,10 +128,10 @@ class WeatherUpdateJob @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
notifier.cancelProgressNotification()
|
notifier.cancelProgressNotification()
|
||||||
// if (BuildConfig.FLAVOR != "freenet" && SettingsManager.getInstance(context).isAppUpdateCheckEnabled) {
|
/*if ((BuildConfig.FLAVOR != "freenet" && SettingsManager.getInstance(context).isAppUpdateCheckEnabled) ||
|
||||||
if ((BuildConfig.FLAVOR != "freenet" && SettingsManager.getInstance(context).isAppUpdateCheckEnabled) ||
|
|
||||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||||
) {
|
) {*/
|
||||||
|
if (BuildConfig.FLAVOR != "freenet" && SettingsManager.getInstance(context).isAppUpdateCheckEnabled) {
|
||||||
try {
|
try {
|
||||||
updateChecker.checkForUpdate(context, forceCheck = false)
|
updateChecker.checkForUpdate(context, forceCheck = false)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,11 @@
|
||||||
package org.breezyweather.common.actionmodecallback
|
package org.breezyweather.common.actionmodecallback
|
||||||
|
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.os.Build
|
|
||||||
import android.view.ActionMode
|
import android.view.ActionMode
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
internal class BreezyFloatingTextActionModeCallback(
|
internal class BreezyFloatingTextActionModeCallback(
|
||||||
private val callback: BreezyTextActionModeCallback,
|
private val callback: BreezyTextActionModeCallback,
|
||||||
) : ActionMode.Callback2() {
|
) : ActionMode.Callback2() {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.view.ActionMode
|
import android.view.ActionMode
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.compose.ui.geometry.Rect
|
import androidx.compose.ui.geometry.Rect
|
||||||
import androidx.compose.ui.platform.TextToolbar
|
import androidx.compose.ui.platform.TextToolbar
|
||||||
import androidx.compose.ui.platform.TextToolbarStatus
|
import androidx.compose.ui.platform.TextToolbarStatus
|
||||||
|
|
@ -49,40 +48,36 @@ internal class BreezyTextToolbar(
|
||||||
textActionModeCallback.rect = rect
|
textActionModeCallback.rect = rect
|
||||||
textActionModeCallback.onCopyRequested = onCopyRequested
|
textActionModeCallback.onCopyRequested = onCopyRequested
|
||||||
textActionModeCallback.onSelectAllRequested = onSelectAllRequested
|
textActionModeCallback.onSelectAllRequested = onSelectAllRequested
|
||||||
textActionModeCallback.onTranslateRequested = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
textActionModeCallback.onTranslateRequested = {
|
||||||
{
|
// Get selected text by copying it, then restore the previous clip
|
||||||
// Get selected text by copying it, then restore the previous clip
|
val clipboardManager = view.context.clipboardManager
|
||||||
val clipboardManager = view.context.clipboardManager
|
val previousClipboard = clipboardManager.primaryClip
|
||||||
val previousClipboard = clipboardManager.primaryClip
|
onCopyRequested?.invoke()
|
||||||
onCopyRequested?.invoke()
|
val text = clipboardManager.text
|
||||||
val text = clipboardManager.text
|
if (previousClipboard != null) {
|
||||||
if (previousClipboard != null) {
|
clipboardManager.setPrimaryClip(previousClipboard)
|
||||||
clipboardManager.setPrimaryClip(previousClipboard)
|
} else {
|
||||||
} else {
|
clipboardManager.setPrimaryClip(ClipData.newPlainText(null, " "))
|
||||||
clipboardManager.setPrimaryClip(ClipData.newPlainText(null, " "))
|
}
|
||||||
}
|
|
||||||
|
val intent = Intent().apply {
|
||||||
val intent = Intent().apply {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
action = Intent.ACTION_TRANSLATE
|
||||||
action = Intent.ACTION_TRANSLATE
|
putExtra(Intent.EXTRA_TEXT, text.trim())
|
||||||
putExtra(Intent.EXTRA_TEXT, text.trim())
|
} else {
|
||||||
} else {
|
action = Intent.ACTION_PROCESS_TEXT
|
||||||
action = Intent.ACTION_PROCESS_TEXT
|
type = "text/plain"
|
||||||
type = "text/plain"
|
putExtra(Intent.EXTRA_PROCESS_TEXT, text.trim())
|
||||||
putExtra(Intent.EXTRA_PROCESS_TEXT, text.trim())
|
putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true)
|
||||||
putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true)
|
}
|
||||||
}
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
}
|
||||||
}
|
|
||||||
|
try {
|
||||||
try {
|
view.context.startActivity(Intent.createChooser(intent, ""))
|
||||||
view.context.startActivity(Intent.createChooser(intent, ""))
|
} catch (e: Exception) {
|
||||||
} catch (e: Exception) {
|
SnackbarHelper.showSnackbar(view.context.getString(R.string.action_translate_no_app))
|
||||||
SnackbarHelper.showSnackbar(view.context.getString(R.string.action_translate_no_app))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
textActionModeCallback.onShareRequested = {
|
textActionModeCallback.onShareRequested = {
|
||||||
// Get selected text by copying it, then restore the previous clip
|
// Get selected text by copying it, then restore the previous clip
|
||||||
|
|
@ -112,16 +107,11 @@ internal class BreezyTextToolbar(
|
||||||
}
|
}
|
||||||
if (actionMode == null) {
|
if (actionMode == null) {
|
||||||
status = TextToolbarStatus.Shown
|
status = TextToolbarStatus.Shown
|
||||||
actionMode =
|
actionMode = TextToolbarHelperMethods.startActionMode(
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
view,
|
||||||
TextToolbarHelperMethods.startActionMode(
|
BreezyFloatingTextActionModeCallback(textActionModeCallback),
|
||||||
view,
|
ActionMode.TYPE_FLOATING
|
||||||
BreezyFloatingTextActionModeCallback(textActionModeCallback),
|
)
|
||||||
ActionMode.TYPE_FLOATING
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
view.startActionMode(BreezyPrimaryTextActionModeCallback(textActionModeCallback))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
actionMode?.invalidate()
|
actionMode?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
@ -155,9 +145,7 @@ internal class BreezyTextToolbar(
|
||||||
* compiled. It is expected that this class will soft-fail verification, but the classes which use
|
* compiled. It is expected that this class will soft-fail verification, but the classes which use
|
||||||
* this method will pass.
|
* this method will pass.
|
||||||
*/
|
*/
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
internal object TextToolbarHelperMethods {
|
internal object TextToolbarHelperMethods {
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
fun startActionMode(
|
fun startActionMode(
|
||||||
view: View,
|
view: View,
|
||||||
actionModeCallback: ActionMode.Callback,
|
actionModeCallback: ActionMode.Callback,
|
||||||
|
|
@ -166,7 +154,6 @@ internal object TextToolbarHelperMethods {
|
||||||
return view.startActionMode(actionModeCallback, type)
|
return view.startActionMode(actionModeCallback, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
fun invalidateContentRect(actionMode: ActionMode) {
|
fun invalidateContentRect(actionMode: ActionMode) {
|
||||||
actionMode.invalidateContentRect()
|
actionMode.invalidateContentRect()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -222,10 +222,6 @@ fun Window.setSystemBarStyle(
|
||||||
val colorSystemBarDark = Color.argb(0x80, 0x1b, 0x1b, 0x1b)
|
val colorSystemBarDark = Color.argb(0x80, 0x1b, 0x1b, 0x1b)
|
||||||
val colorSystemBarLight = Color.argb(0xe6, 0xFF, 0xFF, 0xFF)
|
val colorSystemBarLight = Color.argb(0xe6, 0xFF, 0xFF, 0xFF)
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
||||||
// Always apply a dark shader as a light or transparent status bar is not supported
|
|
||||||
newLightStatus = false
|
|
||||||
}
|
|
||||||
statusBarColor = Color.TRANSPARENT
|
statusBarColor = Color.TRANSPARENT
|
||||||
|
|
||||||
navigationBarColor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && lightStatus) {
|
navigationBarColor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && lightStatus) {
|
||||||
|
|
|
||||||
|
|
@ -655,7 +655,7 @@ abstract class AbstractWidgetConfigActivity : BreezyActivity() {
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
private fun bindWallpaper(checkPermissions: Boolean) {
|
private fun bindWallpaper(checkPermissions: Boolean) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkPermissions) {
|
if (checkPermissions) {
|
||||||
val hasPermission = checkPermissions(0)
|
val hasPermission = checkPermissions(0)
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
return
|
return
|
||||||
|
|
@ -674,7 +674,6 @@ abstract class AbstractWidgetConfigActivity : BreezyActivity() {
|
||||||
* @return true : already got permissions.
|
* @return true : already got permissions.
|
||||||
* false: request permissions.
|
* false: request permissions.
|
||||||
*/
|
*/
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
private fun checkPermissions(requestCode: Int): Boolean {
|
private fun checkPermissions(requestCode: Int): Boolean {
|
||||||
if (!hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
if (!hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||||
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), requestCode)
|
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), requestCode)
|
||||||
|
|
@ -779,10 +778,7 @@ abstract class AbstractWidgetConfigActivity : BreezyActivity() {
|
||||||
updateHostView()
|
updateHostView()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var hasPermission = true
|
val hasPermission = checkPermissions(1)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
hasPermission = checkPermissions(1)
|
|
||||||
}
|
|
||||||
if (hasPermission) {
|
if (hasPermission) {
|
||||||
updateHostView()
|
updateHostView()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ object MultiCityWidgetNotificationIMP : AbstractRemoteViewsPresenter() {
|
||||||
val notification = context.notificationBuilder(Notifications.CHANNEL_WIDGET).apply {
|
val notification = context.notificationBuilder(Notifications.CHANNEL_WIDGET).apply {
|
||||||
priority = NotificationCompat.PRIORITY_MAX
|
priority = NotificationCompat.PRIORITY_MAX
|
||||||
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
if (temperature != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (temperature != null) {
|
||||||
setSmallIcon(
|
setSmallIcon(
|
||||||
IconCompat.createWithBitmap(
|
IconCompat.createWithBitmap(
|
||||||
ResourceHelper.createTempBitmap(context, temperature, temperatureUnit)
|
ResourceHelper.createTempBitmap(context, temperature, temperatureUnit)
|
||||||
|
|
@ -110,7 +110,7 @@ object MultiCityWidgetNotificationIMP : AbstractRemoteViewsPresenter() {
|
||||||
setOnlyAlertOnce(true)
|
setOnlyAlertOnce(true)
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
if (!tempIcon && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (!tempIcon) {
|
||||||
current.weatherCode?.let { weatherCode ->
|
current.weatherCode?.let { weatherCode ->
|
||||||
try {
|
try {
|
||||||
notification.javaClass
|
notification.javaClass
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ object NativeWidgetNotificationIMP : AbstractRemoteViewsPresenter() {
|
||||||
val notification = context.notificationBuilder(Notifications.CHANNEL_WIDGET).apply {
|
val notification = context.notificationBuilder(Notifications.CHANNEL_WIDGET).apply {
|
||||||
priority = NotificationCompat.PRIORITY_MAX
|
priority = NotificationCompat.PRIORITY_MAX
|
||||||
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
if (temperature != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (temperature != null) {
|
||||||
setSmallIcon(
|
setSmallIcon(
|
||||||
IconCompat.createWithBitmap(
|
IconCompat.createWithBitmap(
|
||||||
ResourceHelper.createTempBitmap(context, temperature, temperatureUnit)
|
ResourceHelper.createTempBitmap(context, temperature, temperatureUnit)
|
||||||
|
|
@ -123,7 +123,7 @@ object NativeWidgetNotificationIMP : AbstractRemoteViewsPresenter() {
|
||||||
setContentIntent(getWeatherPendingIntent(context, null, Notifications.ID_WIDGET))
|
setContentIntent(getWeatherPendingIntent(context, null, Notifications.ID_WIDGET))
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
if (!tempIcon && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (!tempIcon) {
|
||||||
current.weatherCode?.let { weatherCode ->
|
current.weatherCode?.let { weatherCode ->
|
||||||
try {
|
try {
|
||||||
notification.javaClass
|
notification.javaClass
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ object WidgetNotificationIMP : AbstractRemoteViewsPresenter() {
|
||||||
val notification = context.notificationBuilder(Notifications.CHANNEL_WIDGET).apply {
|
val notification = context.notificationBuilder(Notifications.CHANNEL_WIDGET).apply {
|
||||||
priority = NotificationCompat.PRIORITY_MAX
|
priority = NotificationCompat.PRIORITY_MAX
|
||||||
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
if (temperature != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (temperature != null) {
|
||||||
setSmallIcon(
|
setSmallIcon(
|
||||||
IconCompat.createWithBitmap(
|
IconCompat.createWithBitmap(
|
||||||
ResourceHelper.createTempBitmap(context, temperature, temperatureUnit)
|
ResourceHelper.createTempBitmap(context, temperature, temperatureUnit)
|
||||||
|
|
@ -139,7 +139,7 @@ object WidgetNotificationIMP : AbstractRemoteViewsPresenter() {
|
||||||
setOnlyAlertOnce(true)
|
setOnlyAlertOnce(true)
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
if (!tempIcon && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (!tempIcon) {
|
||||||
current.weatherCode?.let { weatherCode ->
|
current.weatherCode?.let { weatherCode ->
|
||||||
try {
|
try {
|
||||||
notification.javaClass
|
notification.javaClass
|
||||||
|
|
|
||||||
|
|
@ -362,8 +362,7 @@ class MainActivity : BreezyActivity(), HomeFragment.Callback, ManagementFragment
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
viewModel.locationPermissionsRequest.collect {
|
viewModel.locationPermissionsRequest.collect {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
if (it != null &&
|
||||||
it != null &&
|
|
||||||
it.permissionList.isNotEmpty() &&
|
it.permissionList.isNotEmpty() &&
|
||||||
it.consume()
|
it.consume()
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -348,7 +348,7 @@ class MainActivityViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || !checkPermissions) {
|
if (!checkPermissions) {
|
||||||
updating = true
|
updating = true
|
||||||
SettingsManager.getInstance(getApplication())
|
SettingsManager.getInstance(getApplication())
|
||||||
.weatherManualUpdateLastTimestamp = Date().time
|
.weatherManualUpdateLastTimestamp = Date().time
|
||||||
|
|
|
||||||
|
|
@ -235,35 +235,33 @@ fun BackgroundSettingsScreen(
|
||||||
largeSeparatorItem()
|
largeSeparatorItem()
|
||||||
|
|
||||||
sectionHeaderItem(R.string.settings_background_updates_section_troubleshoot)
|
sectionHeaderItem(R.string.settings_background_updates_section_troubleshoot)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
clickablePreferenceItem(R.string.settings_background_updates_battery_optimization) { id ->
|
||||||
clickablePreferenceItem(R.string.settings_background_updates_battery_optimization) { id ->
|
PreferenceViewWithCard(
|
||||||
PreferenceViewWithCard(
|
titleId = id,
|
||||||
titleId = id,
|
summaryId = R.string.settings_background_updates_battery_optimization_summary,
|
||||||
summaryId = R.string.settings_background_updates_battery_optimization_summary,
|
isFirst = true
|
||||||
isFirst = true
|
) {
|
||||||
) {
|
val packageName: String = context.packageName
|
||||||
val packageName: String = context.packageName
|
if (!context.powerManager.isIgnoringBatteryOptimizations(packageName)) {
|
||||||
if (!context.powerManager.isIgnoringBatteryOptimizations(packageName)) {
|
try {
|
||||||
try {
|
@SuppressLint("BatteryLife")
|
||||||
@SuppressLint("BatteryLife")
|
val intent = Intent().apply {
|
||||||
val intent = Intent().apply {
|
action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
||||||
action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
data = "package:$packageName".toUri()
|
||||||
data = "package:$packageName".toUri()
|
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
}
|
|
||||||
context.startActivity(intent)
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
|
||||||
SnackbarHelper.showSnackbar(
|
|
||||||
context.getString(
|
|
||||||
R.string.settings_background_updates_battery_optimization_activity_not_found
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else {
|
context.startActivity(intent)
|
||||||
|
} catch (e: ActivityNotFoundException) {
|
||||||
SnackbarHelper.showSnackbar(
|
SnackbarHelper.showSnackbar(
|
||||||
context.getString(R.string.settings_background_updates_battery_optimization_disabled)
|
context.getString(
|
||||||
|
R.string.settings_background_updates_battery_optimization_activity_not_found
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SnackbarHelper.showSnackbar(
|
||||||
|
context.getString(R.string.settings_background_updates_battery_optimization_disabled)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -171,28 +171,59 @@ fun LocationSettingsScreen(
|
||||||
sectionFooterItem(R.string.settings_location_section_general)
|
sectionFooterItem(R.string.settings_location_section_general)
|
||||||
largeSeparatorItem()
|
largeSeparatorItem()
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
sectionHeaderItem(R.string.location_service_native)
|
||||||
sectionHeaderItem(R.string.location_service_native)
|
clickablePreferenceItem(R.string.settings_location_access_switch_title) { id ->
|
||||||
clickablePreferenceItem(R.string.settings_location_access_switch_title) { id ->
|
PreferenceViewWithCard(
|
||||||
|
titleId = id,
|
||||||
|
summaryId = if (accessCoarseLocationPermissionState.status == PermissionStatus.Granted) {
|
||||||
|
R.string.settings_location_access_switch_summaryOn
|
||||||
|
} else {
|
||||||
|
R.string.settings_location_access_switch_summaryOff
|
||||||
|
},
|
||||||
|
isFirst = true,
|
||||||
|
isLast = accessBackgroundLocationPermissionState == null &&
|
||||||
|
Build.VERSION.SDK_INT < Build.VERSION_CODES.S,
|
||||||
|
onClick = {
|
||||||
|
if (accessCoarseLocationPermissionState.status != PermissionStatus.Granted) {
|
||||||
|
if (
|
||||||
|
ActivityCompat.shouldShowRequestPermissionRationale(
|
||||||
|
context,
|
||||||
|
Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
accessCoarseLocationPermissionState.launchPermissionRequest()
|
||||||
|
} else {
|
||||||
|
context.openApplicationDetailsSettings()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SnackbarHelper.showSnackbar(
|
||||||
|
context.getString(R.string.settings_location_access_permission_already_granted)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
accessBackgroundLocationPermissionState?.let {
|
||||||
|
smallSeparatorItem()
|
||||||
|
clickablePreferenceItem(R.string.settings_location_access_background_title) { id ->
|
||||||
PreferenceViewWithCard(
|
PreferenceViewWithCard(
|
||||||
titleId = id,
|
titleId = id,
|
||||||
summaryId = if (accessCoarseLocationPermissionState.status == PermissionStatus.Granted) {
|
summaryId = if (it.status == PermissionStatus.Granted) {
|
||||||
R.string.settings_location_access_switch_summaryOn
|
R.string.settings_location_access_background_summaryOn
|
||||||
} else {
|
} else {
|
||||||
R.string.settings_location_access_switch_summaryOff
|
R.string.settings_location_access_background_summaryOff
|
||||||
},
|
},
|
||||||
isFirst = true,
|
enabled = accessCoarseLocationPermissionState.status == PermissionStatus.Granted,
|
||||||
isLast = accessBackgroundLocationPermissionState == null &&
|
isLast = Build.VERSION.SDK_INT < Build.VERSION_CODES.S,
|
||||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.S,
|
|
||||||
onClick = {
|
onClick = {
|
||||||
if (accessCoarseLocationPermissionState.status != PermissionStatus.Granted) {
|
if (it.status != PermissionStatus.Granted) {
|
||||||
if (
|
if (
|
||||||
ActivityCompat.shouldShowRequestPermissionRationale(
|
ActivityCompat.shouldShowRequestPermissionRationale(
|
||||||
context,
|
context,
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION
|
Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
accessCoarseLocationPermissionState.launchPermissionRequest()
|
it.launchPermissionRequest()
|
||||||
} else {
|
} else {
|
||||||
context.openApplicationDetailsSettings()
|
context.openApplicationDetailsSettings()
|
||||||
}
|
}
|
||||||
|
|
@ -204,74 +235,41 @@ fun LocationSettingsScreen(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
accessBackgroundLocationPermissionState?.let {
|
|
||||||
smallSeparatorItem()
|
|
||||||
clickablePreferenceItem(R.string.settings_location_access_background_title) { id ->
|
|
||||||
PreferenceViewWithCard(
|
|
||||||
titleId = id,
|
|
||||||
summaryId = if (it.status == PermissionStatus.Granted) {
|
|
||||||
R.string.settings_location_access_background_summaryOn
|
|
||||||
} else {
|
|
||||||
R.string.settings_location_access_background_summaryOff
|
|
||||||
},
|
|
||||||
enabled = accessCoarseLocationPermissionState.status == PermissionStatus.Granted,
|
|
||||||
isLast = Build.VERSION.SDK_INT < Build.VERSION_CODES.S,
|
|
||||||
onClick = {
|
|
||||||
if (it.status != PermissionStatus.Granted) {
|
|
||||||
if (
|
|
||||||
ActivityCompat.shouldShowRequestPermissionRationale(
|
|
||||||
context,
|
|
||||||
Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
it.launchPermissionRequest()
|
|
||||||
} else {
|
|
||||||
context.openApplicationDetailsSettings()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SnackbarHelper.showSnackbar(
|
|
||||||
context.getString(R.string.settings_location_access_permission_already_granted)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
smallSeparatorItem()
|
|
||||||
clickablePreferenceItem(R.string.settings_location_access_precise_title) { id ->
|
|
||||||
PreferenceViewWithCard(
|
|
||||||
titleId = id,
|
|
||||||
summaryId = if (accessFineLocationPermissionState.status == PermissionStatus.Granted) {
|
|
||||||
R.string.settings_location_access_precise_summaryOn
|
|
||||||
} else {
|
|
||||||
R.string.settings_location_access_precise_summaryOff
|
|
||||||
},
|
|
||||||
enabled = accessCoarseLocationPermissionState.status == PermissionStatus.Granted,
|
|
||||||
isLast = true,
|
|
||||||
onClick = {
|
|
||||||
if (accessFineLocationPermissionState.status != PermissionStatus.Granted) {
|
|
||||||
if (
|
|
||||||
ActivityCompat.shouldShowRequestPermissionRationale(
|
|
||||||
context,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
accessFineLocationPermissionState.launchPermissionRequest()
|
|
||||||
} else {
|
|
||||||
context.openApplicationDetailsSettings()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SnackbarHelper.showSnackbar(
|
|
||||||
context.getString(R.string.settings_location_access_permission_already_granted)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sectionFooterItem(R.string.location_service_native)
|
|
||||||
}
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
smallSeparatorItem()
|
||||||
|
clickablePreferenceItem(R.string.settings_location_access_precise_title) { id ->
|
||||||
|
PreferenceViewWithCard(
|
||||||
|
titleId = id,
|
||||||
|
summaryId = if (accessFineLocationPermissionState.status == PermissionStatus.Granted) {
|
||||||
|
R.string.settings_location_access_precise_summaryOn
|
||||||
|
} else {
|
||||||
|
R.string.settings_location_access_precise_summaryOff
|
||||||
|
},
|
||||||
|
enabled = accessCoarseLocationPermissionState.status == PermissionStatus.Granted,
|
||||||
|
isLast = true,
|
||||||
|
onClick = {
|
||||||
|
if (accessFineLocationPermissionState.status != PermissionStatus.Granted) {
|
||||||
|
if (
|
||||||
|
ActivityCompat.shouldShowRequestPermissionRationale(
|
||||||
|
context,
|
||||||
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
accessFineLocationPermissionState.launchPermissionRequest()
|
||||||
|
} else {
|
||||||
|
context.openApplicationDetailsSettings()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SnackbarHelper.showSnackbar(
|
||||||
|
context.getString(R.string.settings_location_access_permission_already_granted)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sectionFooterItem(R.string.location_service_native)
|
||||||
|
|
||||||
// TODO: Duplicate code from weather sources
|
// TODO: Duplicate code from weather sources
|
||||||
locationSources.filterIsInstance<ConfigurableSource>().forEach { preferenceSource ->
|
locationSources.filterIsInstance<ConfigurableSource>().forEach { preferenceSource ->
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,6 @@ fun ModulesSettingsScreen(
|
||||||
nameArrayId = R.array.notification_styles,
|
nameArrayId = R.array.notification_styles,
|
||||||
enabled = notificationEnabled && hasNotificationPermission,
|
enabled = notificationEnabled && hasNotificationPermission,
|
||||||
card = true,
|
card = true,
|
||||||
isLast = Build.VERSION.SDK_INT < Build.VERSION_CODES.M,
|
|
||||||
onValueChanged = {
|
onValueChanged = {
|
||||||
SettingsManager
|
SettingsManager
|
||||||
.getInstance(context)
|
.getInstance(context)
|
||||||
|
|
@ -333,46 +332,44 @@ fun ModulesSettingsScreen(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
smallSeparatorItem()
|
||||||
smallSeparatorItem()
|
switchPreferenceItem(R.string.settings_modules_notification_temp_icon_switch) { id ->
|
||||||
switchPreferenceItem(R.string.settings_modules_notification_temp_icon_switch) { id ->
|
SwitchPreferenceView(
|
||||||
SwitchPreferenceView(
|
titleId = id,
|
||||||
titleId = id,
|
summaryOnId = R.string.settings_enabled,
|
||||||
summaryOnId = R.string.settings_enabled,
|
summaryOffId = R.string.settings_disabled,
|
||||||
summaryOffId = R.string.settings_disabled,
|
checked = SettingsManager
|
||||||
checked = SettingsManager
|
.getInstance(context)
|
||||||
|
.isWidgetNotificationTemperatureIconEnabled,
|
||||||
|
enabled = notificationEnabled && hasNotificationPermission,
|
||||||
|
onValueChanged = {
|
||||||
|
SettingsManager
|
||||||
.getInstance(context)
|
.getInstance(context)
|
||||||
.isWidgetNotificationTemperatureIconEnabled,
|
.isWidgetNotificationTemperatureIconEnabled = it
|
||||||
enabled = notificationEnabled && hasNotificationPermission,
|
updateNotificationIfNecessary(context)
|
||||||
onValueChanged = {
|
}
|
||||||
SettingsManager
|
)
|
||||||
.getInstance(context)
|
}
|
||||||
.isWidgetNotificationTemperatureIconEnabled = it
|
smallSeparatorItem()
|
||||||
updateNotificationIfNecessary(context)
|
switchPreferenceItem(R.string.settings_modules_notification_feels_like_switch) { id ->
|
||||||
}
|
SwitchPreferenceView(
|
||||||
)
|
titleId = id,
|
||||||
}
|
summaryOnId = R.string.settings_enabled,
|
||||||
smallSeparatorItem()
|
summaryOffId = R.string.settings_disabled,
|
||||||
switchPreferenceItem(R.string.settings_modules_notification_feels_like_switch) { id ->
|
checked = SettingsManager
|
||||||
SwitchPreferenceView(
|
.getInstance(context)
|
||||||
titleId = id,
|
.isWidgetNotificationUsingFeelsLike,
|
||||||
summaryOnId = R.string.settings_enabled,
|
enabled = notificationEnabled &&
|
||||||
summaryOffId = R.string.settings_disabled,
|
hasNotificationPermission &&
|
||||||
checked = SettingsManager
|
notificationTemperatureIconEnabled,
|
||||||
|
isLast = true,
|
||||||
|
onValueChanged = {
|
||||||
|
SettingsManager
|
||||||
.getInstance(context)
|
.getInstance(context)
|
||||||
.isWidgetNotificationUsingFeelsLike,
|
.isWidgetNotificationUsingFeelsLike = it
|
||||||
enabled = notificationEnabled &&
|
updateNotificationIfNecessary(context)
|
||||||
hasNotificationPermission &&
|
}
|
||||||
notificationTemperatureIconEnabled,
|
)
|
||||||
isLast = true,
|
|
||||||
onValueChanged = {
|
|
||||||
SettingsManager
|
|
||||||
.getInstance(context)
|
|
||||||
.isWidgetNotificationUsingFeelsLike = it
|
|
||||||
updateNotificationIfNecessary(context)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sectionFooterItem(R.string.settings_modules_section_notification_widget)
|
sectionFooterItem(R.string.settings_modules_section_notification_widget)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,6 @@ object ResourceHelper {
|
||||||
return provider.getMinimalXmlIcon(code, daytime)
|
return provider.getMinimalXmlIcon(code, daytime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
fun getMinimalIcon(
|
fun getMinimalIcon(
|
||||||
provider: ResourceProvider,
|
provider: ResourceProvider,
|
||||||
code: WeatherCode,
|
code: WeatherCode,
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,6 @@ class ChronusResourceProvider(
|
||||||
return mDefaultProvider.getMinimalXmlIcon(code, dayTime)
|
return mDefaultProvider.getMinimalXmlIcon(code, dayTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
override fun getMinimalIcon(code: WeatherCode?, dayTime: Boolean): Icon {
|
override fun getMinimalIcon(code: WeatherCode?, dayTime: Boolean): Icon {
|
||||||
return mDefaultProvider.getMinimalIcon(code, dayTime)
|
return mDefaultProvider.getMinimalIcon(code, dayTime)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,6 @@ class DefaultResourceProvider : ResourceProvider() {
|
||||||
return getDrawable(getMiniXmlIconName(code, dayTime))!!
|
return getDrawable(getMiniXmlIconName(code, dayTime))!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
override fun getMinimalIcon(code: WeatherCode?, dayTime: Boolean): Icon {
|
override fun getMinimalIcon(code: WeatherCode?, dayTime: Boolean): Icon {
|
||||||
return Objects.requireNonNull(
|
return Objects.requireNonNull(
|
||||||
Icon.createWithResource(
|
Icon.createWithResource(
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,7 @@ import android.content.pm.PackageManager
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.graphics.drawable.Icon
|
import android.graphics.drawable.Icon
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import androidx.annotation.IntRange
|
import androidx.annotation.IntRange
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.annotation.Size
|
import androidx.annotation.Size
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import breezyweather.domain.weather.reference.WeatherCode
|
import breezyweather.domain.weather.reference.WeatherCode
|
||||||
|
|
@ -338,12 +336,11 @@ open class IconPackResourcesProvider(
|
||||||
if (mConfig.hasMinimalIcons) {
|
if (mConfig.hasMinimalIcons) {
|
||||||
return getDrawable(getMiniXmlIconName(code, dayTime))!!
|
return getDrawable(getMiniXmlIconName(code, dayTime))!!
|
||||||
}
|
}
|
||||||
} catch (ignore: Exception) {
|
} catch (_: Exception) {
|
||||||
}
|
}
|
||||||
return mDefaultProvider.getMinimalXmlIcon(code, dayTime)
|
return mDefaultProvider.getMinimalXmlIcon(code, dayTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
override fun getMinimalIcon(code: WeatherCode?, dayTime: Boolean): Icon {
|
override fun getMinimalIcon(code: WeatherCode?, dayTime: Boolean): Icon {
|
||||||
try {
|
try {
|
||||||
if (mConfig.hasMinimalIcons) {
|
if (mConfig.hasMinimalIcons) {
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ abstract class ResourceProvider {
|
||||||
abstract fun getWeatherAnimators(code: WeatherCode?, dayTime: Boolean): Array<Animator?>
|
abstract fun getWeatherAnimators(code: WeatherCode?, dayTime: Boolean): Array<Animator?>
|
||||||
|
|
||||||
// minimal icon.
|
// minimal icon.
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
abstract fun getMinimalIcon(code: WeatherCode?, dayTime: Boolean): Icon
|
abstract fun getMinimalIcon(code: WeatherCode?, dayTime: Boolean): Icon
|
||||||
abstract fun getMinimalLightIcon(code: WeatherCode?, dayTime: Boolean): Drawable
|
abstract fun getMinimalLightIcon(code: WeatherCode?, dayTime: Boolean): Drawable
|
||||||
abstract fun getMinimalLightIconUri(code: WeatherCode?, dayTime: Boolean): Uri
|
abstract fun getMinimalLightIconUri(code: WeatherCode?, dayTime: Boolean): Uri
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget as KotlinJvmTarget
|
||||||
|
|
||||||
object AndroidConfig {
|
object AndroidConfig {
|
||||||
const val COMPILE_SDK = 36
|
const val COMPILE_SDK = 36
|
||||||
const val MIN_SDK = 21
|
const val MIN_SDK = 23
|
||||||
const val TARGET_SDK = 36
|
const val TARGET_SDK = 36
|
||||||
const val BUILD_TOOLS = "35.0.1"
|
const val BUILD_TOOLS = "35.0.1"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue