From d3b623cf13bff5fb2af4dc7b51cb6a7e93df6095 Mon Sep 17 00:00:00 2001 From: azuo Date: Mon, 13 Sep 2021 19:28:47 +0800 Subject: [PATCH] Add ACCESS_BACKGROUND_LOCATION permission required by Android 11. --- app/src/main/AndroidManifest.xml | 26 +++++---- .../anotherwidget/helpers/WeatherHelper.kt | 15 ++++- .../network/WeatherNetworkApi.kt | 7 +++ .../anotherwidget/services/LocationService.kt | 8 +-- .../activities/tabs/CustomLocationActivity.kt | 47 ++++------------ .../tabs/WeatherProviderActivity.kt | 4 +- .../ui/fragments/tabs/WeatherFragment.kt | 55 +++++++++++++------ 7 files changed, 87 insertions(+), 75 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 65950db..f6aaa1e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + @@ -13,6 +14,7 @@ + - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt index 26b3ce7..f0ac243 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt @@ -21,11 +21,20 @@ object WeatherHelper { suspend fun updateWeather(context: Context) { Kotpref.init(context) - val networkApi = WeatherNetworkApi(context) if (Preferences.customLocationAdd != "") { - networkApi.updateWeather() - } else if (context.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) { + WeatherNetworkApi(context).updateWeather() + } else if (context.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) && + (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R || + context.checkGrantedPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) + ) { LocationService.requestNewLocation(context) + } else { + Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_missing_location) + Preferences.weatherProviderError = "" + removeWeather(context) + org.greenrobot.eventbus.EventBus.getDefault().post( + com.tommasoberlose.anotherwidget.ui.fragments.MainFragment.UpdateUiMessageEvent() + ) } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/network/WeatherNetworkApi.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/network/WeatherNetworkApi.kt index 436944f..3b2c513 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/network/WeatherNetworkApi.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/network/WeatherNetworkApi.kt @@ -42,6 +42,13 @@ class WeatherNetworkApi(val context: Context) { Constants.WeatherProvider.YR -> useYrProvider(context) } } else { + if (!Preferences.showWeather) + Preferences.weatherProviderError = context.getString(R.string.show_weather_not_visible) + else { + Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_missing_location) + Preferences.weatherProviderError = "" + } + WeatherHelper.removeWeather( context ) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/services/LocationService.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/services/LocationService.kt index 73bb497..44a1f2d 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/services/LocationService.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/services/LocationService.kt @@ -18,6 +18,7 @@ import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment +import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import kotlinx.coroutines.* import org.greenrobot.eventbus.EventBus import java.lang.Exception @@ -37,10 +38,9 @@ class LocationService : Service() { startForeground(LOCATION_ACCESS_NOTIFICATION_ID, getLocationAccessNotification()) job?.cancel() job = GlobalScope.launch(Dispatchers.IO) { - if (ActivityCompat.checkSelfPermission( - this@LocationService, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED + if (checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) && + (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R || + checkGrantedPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) ) { if (com.google.android.gms.common.GoogleApiAvailability.getInstance() .isGooglePlayServicesAvailable(this@LocationService) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/CustomLocationActivity.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/CustomLocationActivity.kt index 3e510ff..77ec9a0 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/CustomLocationActivity.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/CustomLocationActivity.kt @@ -46,11 +46,16 @@ class CustomLocationActivity : AppCompatActivity() { adapter = SlimAdapter.create() adapter .register(R.layout.custom_location_item) { _, injector -> - injector - .text(R.id.text, getString(R.string.custom_location_gps)) - .clicked(R.id.text) { - requirePermission() + injector.text(R.id.text, getString(R.string.custom_location_gps)) + injector.clicked(R.id.text) { + Preferences.bulk { + remove(Preferences::customLocationLat) + remove(Preferences::customLocationLon) + remove(Preferences::customLocationAdd) } + setResult(Activity.RESULT_OK) + finish() + } } .register
(R.layout.custom_location_item) { item, injector -> injector.text(R.id.text, item.getAddressLine(0) ?: "") @@ -59,9 +64,9 @@ class CustomLocationActivity : AppCompatActivity() { customLocationLat = item.latitude.toString() customLocationLon = item.longitude.toString() customLocationAdd = item.getAddressLine(0) ?: "" - setResult(Activity.RESULT_OK) - finish() } + setResult(Activity.RESULT_OK) + finish() } } .attachTo(binding.listView) @@ -115,36 +120,6 @@ class CustomLocationActivity : AppCompatActivity() { }) } - private fun requirePermission() { - Dexter.withContext(this) - .withPermissions( - Manifest.permission.ACCESS_FINE_LOCATION - ).withListener(object: MultiplePermissionsListener { - override fun onPermissionsChecked(report: MultiplePermissionsReport?) { - report?.let { - if (report.areAllPermissionsGranted()){ - Preferences.bulk { - remove(Preferences::customLocationLat) - remove(Preferences::customLocationLon) - remove(Preferences::customLocationAdd) - } - setResult(Activity.RESULT_OK) - finish() - } - } - } - override fun onPermissionRationaleShouldBeShown( - permissions: MutableList?, - token: PermissionToken? - ) { - // Remember to invoke this method when the custom rationale is closed - // or just by default if you don't want to use any custom rationale. - token?.continuePermissionRequest() - } - }) - .check() - } - private fun setupListener() { binding.actionBack.setOnClickListener { onBackPressed() diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/WeatherProviderActivity.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/WeatherProviderActivity.kt index ec5297a..4773cf8 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/WeatherProviderActivity.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/WeatherProviderActivity.kt @@ -127,11 +127,11 @@ class WeatherProviderActivity : AppCompatActivity() { private fun subscribeUi(viewModel: WeatherProviderViewModel) { viewModel.weatherProviderError.observe(this) { - updateListItem() + binding.listView.postDelayed({ updateListItem() }, 300) } viewModel.weatherProviderLocationError.observe(this) { - updateListItem() + binding.listView.postDelayed({ updateListItem() }, 300) } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/WeatherFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/WeatherFragment.kt index fd4a3a9..4fc5644 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/WeatherFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/WeatherFragment.kt @@ -91,16 +91,17 @@ class WeatherFragment : Fragment() { viewModel.weatherProvider.observe(viewLifecycleOwner) { maintainScrollPosition { binding.labelWeatherProvider.text = WeatherHelper.getProviderName(requireContext(), Constants.WeatherProvider.fromInt(it)!!) - checkWeatherProviderConfig() } } viewModel.weatherProviderError.observe(viewLifecycleOwner) { checkWeatherProviderConfig() + checkLocationPermission() } viewModel.weatherProviderLocationError.observe(viewLifecycleOwner) { checkWeatherProviderConfig() + checkLocationPermission() } viewModel.customLocationAdd.observe(viewLifecycleOwner) { @@ -108,6 +109,7 @@ class WeatherFragment : Fragment() { binding.labelCustomLocation.text = if (it == "") getString(R.string.custom_location_gps) else it } + checkWeatherProviderConfig() checkLocationPermission() } @@ -116,43 +118,50 @@ class WeatherFragment : Fragment() { binding.tempUnit.text = if (it == "F") getString(R.string.fahrenheit) else getString(R.string.celsius) } - checkLocationPermission() } viewModel.weatherRefreshPeriod.observe(viewLifecycleOwner) { maintainScrollPosition { binding.labelWeatherRefreshPeriod.text = getString(SettingsStringHelper.getRefreshPeriodString(it)) } - checkLocationPermission() } viewModel.weatherIconPack.observe(viewLifecycleOwner) { maintainScrollPosition { binding.labelWeatherIconPack.text = getString(R.string.settings_weather_icon_pack_default).format((it + 1)) } - checkLocationPermission() } } private fun checkLocationPermission() { - if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) { + if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) && + (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R || + requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) + ) { binding.locationPermissionAlert.isVisible = false - WeatherReceiver.setUpdates(requireContext()) - } else if (Preferences.showWeather && Preferences.customLocationAdd == "") { + } else if (Preferences.customLocationAdd == "") { binding.locationPermissionAlert.isVisible = true binding.locationPermissionAlert.setOnClickListener { requirePermission() } + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R && + requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) + ) { + val text = getString(R.string.action_grant_permission) + " - " + + requireContext().packageManager.backgroundPermissionOptionLabel + binding.locationPermissionAlert.text = text + } + binding.weatherProviderLocationError.isVisible = false } else { binding.locationPermissionAlert.isVisible = false } } private fun checkWeatherProviderConfig() { - binding.weatherProviderError.isVisible = Preferences.showWeather && Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" + binding.weatherProviderError.isVisible = Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" binding.weatherProviderError.text = Preferences.weatherProviderError - binding.weatherProviderLocationError.isVisible = Preferences.showWeather && Preferences.weatherProviderLocationError != "" + binding.weatherProviderLocationError.isVisible = Preferences.weatherProviderLocationError != "" binding.weatherProviderLocationError.text = Preferences.weatherProviderLocationError } @@ -177,11 +186,11 @@ class WeatherFragment : Fragment() { .addItem(getString(R.string.celsius), "C") .addOnSelectItemListener { value -> if (value != Preferences.weatherTempUnit) { + Preferences.weatherTempUnit = value viewLifecycleOwner.lifecycleScope.launch { WeatherHelper.updateWeather(requireContext()) } } - Preferences.weatherTempUnit = value }.show() } @@ -193,7 +202,10 @@ class WeatherFragment : Fragment() { } dialog .addOnSelectItemListener { value -> - Preferences.weatherRefreshPeriod = value + if (value != Preferences.weatherRefreshPeriod) { + Preferences.weatherRefreshPeriod = value + WeatherReceiver.setUpdates(requireContext()) + } }.show() } @@ -206,12 +218,12 @@ class WeatherFragment : Fragment() { if (resultCode == Activity.RESULT_OK) { when (requestCode) { Constants.RESULT_CODE_CUSTOM_LOCATION -> { - WeatherReceiver.setUpdates(requireContext()) - checkLocationPermission() - } - RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code -> { - checkLocationPermission() + viewLifecycleOwner.lifecycleScope.launch { + WeatherHelper.updateWeather(requireContext()) + } } + //RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code -> { + //} } } super.onActivityResult(requestCode, resultCode, data) @@ -220,12 +232,19 @@ class WeatherFragment : Fragment() { private fun requirePermission() { Dexter.withContext(requireContext()) .withPermissions( - Manifest.permission.ACCESS_FINE_LOCATION + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R && + requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) + Manifest.permission.ACCESS_BACKGROUND_LOCATION + else + Manifest.permission.ACCESS_FINE_LOCATION ).withListener(object: MultiplePermissionsListener { override fun onPermissionsChecked(report: MultiplePermissionsReport?) { report?.let { - if (report.areAllPermissionsGranted()){ + if (report.areAllPermissionsGranted()) { checkLocationPermission() + viewLifecycleOwner.lifecycleScope.launch { + WeatherHelper.updateWeather(requireContext()) + } } } }