mirror of
https://github.com/hmalik144/Weather-apps.git
synced 2025-12-10 02:05:20 +00:00
Permissions playstore dialog (#22)
- Permissions dispatcher added - Updated to widget api 31+ - circleci.yml updated - fastlane file fixed
This commit is contained in:
@@ -45,21 +45,19 @@ commands:
|
|||||||
default: "AtlasWeather"
|
default: "AtlasWeather"
|
||||||
package_suffix:
|
package_suffix:
|
||||||
type: string
|
type: string
|
||||||
default: "atlas_weather"
|
default: "atlasWeather"
|
||||||
steps:
|
steps:
|
||||||
- android/start-emulator-and-run-tests:
|
- android/start-emulator-and-run-tests:
|
||||||
post-emulator-launch-assemble-command: ./gradlew assemble<< parameters.flavour >>DebugAndroidTest
|
post-emulator-launch-assemble-command: ./gradlew assemble<< parameters.flavour >>DebugAndroidTest
|
||||||
test-command: ./gradlew connected<< parameters.flavour >>DebugAndroidTest --continue
|
test-command: ./gradlew connected<< parameters.flavour >>DebugAndroidTest --continue
|
||||||
system-image: system-images;android-26;google_apis;x86
|
system-image: system-images;android-26;google_apis;x86
|
||||||
pull-data: true
|
|
||||||
pull-data-target: ~/app-data
|
|
||||||
# store screenshots for failed ui tests
|
# store screenshots for failed ui tests
|
||||||
- when:
|
- when:
|
||||||
condition: on_fail
|
condition: on_fail
|
||||||
steps:
|
steps:
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: ~/app-data
|
path: app/build/outputs/connected_android_test_additional_output/monoWeatherDebugAndroidTest/connected
|
||||||
destination: screenshots
|
destination: connected_android_test
|
||||||
# store test reports
|
# store test reports
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: app/build/reports/androidTests/connected
|
path: app/build/reports/androidTests/connected
|
||||||
@@ -97,9 +95,6 @@ jobs:
|
|||||||
flavour:
|
flavour:
|
||||||
type: string
|
type: string
|
||||||
default: "AtlasWeather"
|
default: "AtlasWeather"
|
||||||
package_suffix:
|
|
||||||
type: string
|
|
||||||
default: "atlas_weather"
|
|
||||||
# These next lines define the Android machine image executor.
|
# These next lines define the Android machine image executor.
|
||||||
# See: https://circleci.com/docs/2.0/executor-types/
|
# See: https://circleci.com/docs/2.0/executor-types/
|
||||||
executor:
|
executor:
|
||||||
@@ -111,8 +106,27 @@ jobs:
|
|||||||
- setup_repo
|
- setup_repo
|
||||||
- run_tests:
|
- run_tests:
|
||||||
flavour: << parameters.flavour >>
|
flavour: << parameters.flavour >>
|
||||||
|
run_instrumentation_test:
|
||||||
|
# Parameters used for determining
|
||||||
|
parameters:
|
||||||
|
flavour:
|
||||||
|
type: string
|
||||||
|
default: "AtlasWeather"
|
||||||
|
package_suffix:
|
||||||
|
type: string
|
||||||
|
default: "atlasWeather"
|
||||||
|
# These next lines define the Android machine image executor.
|
||||||
|
# See: https://circleci.com/docs/2.0/executor-types/
|
||||||
|
executor:
|
||||||
|
name: android/android-machine
|
||||||
|
tag: 2023.05.1
|
||||||
|
# Add steps to the job
|
||||||
|
# See: https://circleci.com/docs/2.0/configuration-reference/#steps
|
||||||
|
steps:
|
||||||
|
- setup_repo
|
||||||
- run_ui_tests:
|
- run_ui_tests:
|
||||||
flavour: << parameters.flavour >>
|
flavour: << parameters.flavour >>
|
||||||
|
package_suffix: << parameters.package_suffix >>
|
||||||
deploy-to-playstore:
|
deploy-to-playstore:
|
||||||
parameters:
|
parameters:
|
||||||
flavour:
|
flavour:
|
||||||
@@ -137,11 +151,19 @@ workflows:
|
|||||||
- build-and-test:
|
- build-and-test:
|
||||||
context: appttude
|
context: appttude
|
||||||
flavour: "MonoWeather"
|
flavour: "MonoWeather"
|
||||||
package_suffix: "monoWeather"
|
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
ignore:
|
ignore:
|
||||||
- main_atlas
|
- main_atlas
|
||||||
|
- run_instrumentation_test:
|
||||||
|
context: appttude
|
||||||
|
flavour: "MonoWeather"
|
||||||
|
package_suffix: "monoWeather"
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- main_mono
|
||||||
- deploy-to-playstore:
|
- deploy-to-playstore:
|
||||||
context: appttude
|
context: appttude
|
||||||
flavour: "MonoWeather"
|
flavour: "MonoWeather"
|
||||||
@@ -156,11 +178,19 @@ workflows:
|
|||||||
- build-and-test:
|
- build-and-test:
|
||||||
context: appttude
|
context: appttude
|
||||||
flavour: "AtlasWeather"
|
flavour: "AtlasWeather"
|
||||||
package_suffix: "atlas_weather"
|
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
ignore:
|
ignore:
|
||||||
- main_mono
|
- main_mono
|
||||||
|
- run_instrumentation_test:
|
||||||
|
context: appttude
|
||||||
|
flavour: "AtlasWeather"
|
||||||
|
package_suffix: "atlasWeather"
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- main_atlas
|
||||||
- deploy-to-playstore:
|
- deploy-to-playstore:
|
||||||
context: appttude
|
context: appttude
|
||||||
flavour: "AtlasWeather"
|
flavour: "AtlasWeather"
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -91,7 +91,7 @@ gen-external-apklibs
|
|||||||
.idea/jarRepositorie
|
.idea/jarRepositorie
|
||||||
|
|
||||||
# Gem/fastlane
|
# Gem/fastlane
|
||||||
/Gemfile.lock
|
Gemfile.lock
|
||||||
/fastlane/report.xml
|
/fastlane/report.xml
|
||||||
# Google play files
|
# Google play files
|
||||||
/google-play-key.json
|
/google-play-key.json
|
||||||
|
|||||||
@@ -5,13 +5,20 @@ plugins {
|
|||||||
id 'kotlin-kapt'
|
id 'kotlin-kapt'
|
||||||
id 'androidx.navigation.safeargs'
|
id 'androidx.navigation.safeargs'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def relStorePassword = System.getenv("RELEASE_STORE_PASSWORD")
|
||||||
|
def relKeyPassword = System.getenv("RELEASE_KEY_PASSWORD")
|
||||||
|
def relKeyAlias = System.getenv("RELEASE_KEY_ALIAS")
|
||||||
|
|
||||||
|
def keystorePath = System.getenv('PWD') + "/app/keystore.jks"
|
||||||
|
def keystore = file(keystorePath).exists() ? file(keystorePath) : null
|
||||||
android {
|
android {
|
||||||
lintOptions {
|
lintOptions {
|
||||||
abortOnError false
|
abortOnError false
|
||||||
}
|
}
|
||||||
compileSdkVersion 33
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.appttude.h_mal.atlas_weather"
|
applicationId "com.appttude.h_mal.atlas_weather"
|
||||||
|
compileSdk 33
|
||||||
minSdkVersion 26
|
minSdkVersion 26
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode 5
|
versionCode 5
|
||||||
@@ -40,6 +47,14 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
storePassword relStorePassword
|
||||||
|
keyPassword relKeyPassword
|
||||||
|
keyAlias relKeyAlias
|
||||||
|
storeFile keystore
|
||||||
|
}
|
||||||
|
}
|
||||||
testOptions {
|
testOptions {
|
||||||
unitTests {
|
unitTests {
|
||||||
includeAndroidResources = true
|
includeAndroidResources = true
|
||||||
@@ -48,6 +63,7 @@ android {
|
|||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
@@ -99,6 +115,7 @@ dependencies {
|
|||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
implementation 'com.google.android.material:material:1.2.1'
|
implementation 'com.google.android.material:material:1.2.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
|
implementation 'androidx.fragment:fragment:1.2.0'
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||||
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
|
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
|
||||||
@@ -187,4 +204,8 @@ dependencies {
|
|||||||
|
|
||||||
/ * screenshot library * /
|
/ * screenshot library * /
|
||||||
androidTestImplementation 'tools.fastlane:screengrab:2.1.1'
|
androidTestImplementation 'tools.fastlane:screengrab:2.1.1'
|
||||||
|
/ * Permissions dispatcher * /
|
||||||
|
def dispatcher_ver = "4.9.2"
|
||||||
|
implementation "com.github.permissions-dispatcher:permissionsdispatcher:${dispatcher_ver}"
|
||||||
|
kapt "com.github.permissions-dispatcher:permissionsdispatcher-processor:${dispatcher_ver}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,21 +13,31 @@ import androidx.navigation.ui.onNavDestinationSelected
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
||||||
|
import com.appttude.h_mal.atlas_weather.base.BaseFragment
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.Forecast
|
import com.appttude.h_mal.atlas_weather.model.forecast.Forecast
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
import com.appttude.h_mal.atlas_weather.ui.dialog.PermissionsDeclarationDialog
|
||||||
import com.appttude.h_mal.atlas_weather.ui.home.adapter.WeatherRecyclerAdapter
|
import com.appttude.h_mal.atlas_weather.ui.home.adapter.WeatherRecyclerAdapter
|
||||||
|
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.MainViewModel
|
import com.appttude.h_mal.atlas_weather.viewmodel.MainViewModel
|
||||||
import kotlinx.android.synthetic.main.fragment_home.*
|
import kotlinx.android.synthetic.main.fragment_home.*
|
||||||
|
import permissions.dispatcher.NeedsPermission
|
||||||
|
import permissions.dispatcher.OnNeverAskAgain
|
||||||
|
import permissions.dispatcher.OnPermissionDenied
|
||||||
|
import permissions.dispatcher.OnShowRationale
|
||||||
|
import permissions.dispatcher.PermissionRequest
|
||||||
|
import permissions.dispatcher.RuntimePermissions
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple [Fragment] subclass.
|
* A simple [Fragment] subclass.
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
|
@RuntimePermissions
|
||||||
class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
||||||
private lateinit var recyclerAdapter: WeatherRecyclerAdapter
|
|
||||||
|
lateinit var recyclerAdapter: WeatherRecyclerAdapter
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
@@ -36,35 +46,28 @@ class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
|||||||
|
|
||||||
swipe_refresh.apply {
|
swipe_refresh.apply {
|
||||||
setOnRefreshListener {
|
setOnRefreshListener {
|
||||||
getPermissionResult(ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
showLocationWithPermissionCheck()
|
||||||
viewModel.fetchData()
|
|
||||||
isRefreshing = true
|
isRefreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
recyclerAdapter = WeatherRecyclerAdapter(itemClick = {
|
recyclerAdapter = WeatherRecyclerAdapter(itemClick = {
|
||||||
navigateToFurtherDetails(it)
|
navigateToFurtherDetails(it)
|
||||||
})
|
})
|
||||||
|
|
||||||
forecast_listview.apply {
|
forecast_listview.adapter = recyclerAdapter
|
||||||
layoutManager = LinearLayoutManager(context)
|
|
||||||
adapter = recyclerAdapter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
|
showLocationWithPermissionCheck()
|
||||||
getPermissionResult(ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
|
||||||
viewModel.fetchData()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccess(data: Any?) {
|
override fun onSuccess(data: Any?) {
|
||||||
super.onSuccess(data)
|
super.onSuccess(data)
|
||||||
swipe_refresh.isRefreshing = false
|
swipe_refresh.isRefreshing = false
|
||||||
|
|
||||||
if (data is WeatherDisplay) {
|
if (data is WeatherDisplay) {
|
||||||
recyclerAdapter.addCurrent(data)
|
recyclerAdapter.addCurrent(data)
|
||||||
}
|
}
|
||||||
@@ -75,14 +78,8 @@ class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
|||||||
swipe_refresh.isRefreshing = false
|
swipe_refresh.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
|
||||||
override fun permissionsGranted() {
|
|
||||||
viewModel.fetchData()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun navigateToFurtherDetails(forecast: Forecast) {
|
private fun navigateToFurtherDetails(forecast: Forecast) {
|
||||||
val directions = HomeFragmentDirections
|
val directions = HomeFragmentDirections.actionHomeFragmentToFurtherDetailsFragment(forecast)
|
||||||
.actionHomeFragmentToFurtherDetailsFragment(forecast)
|
|
||||||
navigateTo(directions)
|
navigateTo(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,4 +92,35 @@ class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
|||||||
val navController = findNavController(requireActivity(), R.id.container)
|
val navController = findNavController(requireActivity(), R.id.container)
|
||||||
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
|
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
// NOTE: delegate the permission handling to generated method
|
||||||
|
onRequestPermissionsResult(requestCode, grantResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
|
@NeedsPermission(ACCESS_COARSE_LOCATION)
|
||||||
|
fun showLocation() {
|
||||||
|
viewModel.fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnShowRationale(ACCESS_COARSE_LOCATION)
|
||||||
|
fun showRationaleForLocation(request: PermissionRequest) {
|
||||||
|
PermissionsDeclarationDialog(requireContext()).showDialog({
|
||||||
|
request.proceed()
|
||||||
|
}, {
|
||||||
|
request.cancel()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnPermissionDenied(ACCESS_COARSE_LOCATION)
|
||||||
|
fun onLocationDenied() {
|
||||||
|
displayToast("Location permissions have been denied")
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnNeverAskAgain(ACCESS_COARSE_LOCATION)
|
||||||
|
fun onLocationNeverAskAgain() {
|
||||||
|
displayToast("Location permissions have been to never ask again")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ package com.appttude.h_mal.atlas_weather.ui.world
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
import com.appttude.h_mal.atlas_weather.base.BaseFragment
|
||||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||||
import com.appttude.h_mal.atlas_weather.utils.goBack
|
import com.appttude.h_mal.atlas_weather.utils.goBack
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import android.view.View
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
|
import com.appttude.h_mal.atlas_weather.base.BaseFragment
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
|
||||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||||
import kotlinx.android.synthetic.atlasWeather.fragment_add_location.floatingActionButton
|
import kotlinx.android.synthetic.atlasWeather.fragment_add_location.floatingActionButton
|
||||||
|
|||||||
@@ -1,29 +1,22 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.base
|
package com.appttude.h_mal.atlas_weather.base
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup.LayoutParams
|
import android.view.ViewGroup.LayoutParams
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
import android.view.ViewGroup.inflate
|
import android.view.ViewGroup.inflate
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.ViewModelLazy
|
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.helper.GenericsHelper.getGenericClassAt
|
|
||||||
import com.appttude.h_mal.atlas_weather.model.ViewState
|
|
||||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||||
import com.appttude.h_mal.atlas_weather.utils.hide
|
import com.appttude.h_mal.atlas_weather.utils.hide
|
||||||
import com.appttude.h_mal.atlas_weather.utils.show
|
import com.appttude.h_mal.atlas_weather.utils.show
|
||||||
import com.appttude.h_mal.atlas_weather.utils.triggerAnimation
|
import com.appttude.h_mal.atlas_weather.utils.triggerAnimation
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.baseViewModels.BaseViewModel
|
|
||||||
import org.kodein.di.KodeinAware
|
import org.kodein.di.KodeinAware
|
||||||
import org.kodein.di.android.kodein
|
import org.kodein.di.android.kodein
|
||||||
import org.kodein.di.generic.instance
|
|
||||||
|
|
||||||
abstract class BaseActivity : AppCompatActivity(), KodeinAware {
|
abstract class BaseActivity : AppCompatActivity(), KodeinAware {
|
||||||
|
|
||||||
private lateinit var loadingView: View
|
private var loadingView: View? = null
|
||||||
|
|
||||||
override val kodein by kodein()
|
override val kodein by kodein()
|
||||||
|
|
||||||
@@ -36,9 +29,9 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAware {
|
|||||||
*/
|
*/
|
||||||
private fun instantiateLoadingView() {
|
private fun instantiateLoadingView() {
|
||||||
loadingView = inflate(this, R.layout.progress_layout, null)
|
loadingView = inflate(this, R.layout.progress_layout, null)
|
||||||
loadingView.setOnClickListener(null)
|
loadingView?.setOnClickListener(null)
|
||||||
addContentView(loadingView, LayoutParams(MATCH_PARENT, MATCH_PARENT))
|
addContentView(loadingView, LayoutParams(MATCH_PARENT, MATCH_PARENT))
|
||||||
loadingView.hide()
|
loadingView?.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
@@ -55,14 +48,14 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAware {
|
|||||||
* Called in case of success or some data emitted from the liveData in viewModel
|
* Called in case of success or some data emitted from the liveData in viewModel
|
||||||
*/
|
*/
|
||||||
open fun onStarted() {
|
open fun onStarted() {
|
||||||
loadingView.fadeIn()
|
loadingView?.fadeIn()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in case of success or some data emitted from the liveData in viewModel
|
* Called in case of success or some data emitted from the liveData in viewModel
|
||||||
*/
|
*/
|
||||||
open fun onSuccess(data: Any?) {
|
open fun onSuccess(data: Any?) {
|
||||||
loadingView.fadeOut()
|
loadingView?.fadeOut()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,7 +63,7 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAware {
|
|||||||
*/
|
*/
|
||||||
open fun onFailure(error: Any?) {
|
open fun onFailure(error: Any?) {
|
||||||
if (error is String) displayToast(error)
|
if (error is String) displayToast(error)
|
||||||
loadingView.fadeOut()
|
loadingView?.fadeOut()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun View.fadeIn() = apply {
|
private fun View.fadeIn() = apply {
|
||||||
@@ -85,7 +78,7 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAware {
|
|||||||
|
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
loadingView.hide()
|
loadingView?.hide()
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,26 +1,14 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.ui
|
package com.appttude.h_mal.atlas_weather.base
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.createViewModelLazy
|
import androidx.fragment.app.createViewModelLazy
|
||||||
import androidx.lifecycle.Observer
|
import com.appttude.h_mal.atlas_weather.base.baseViewModels.BaseViewModel
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
||||||
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
|
||||||
import com.appttude.h_mal.atlas_weather.base.BaseActivity
|
|
||||||
import com.appttude.h_mal.atlas_weather.helper.GenericsHelper.getGenericClassAt
|
import com.appttude.h_mal.atlas_weather.helper.GenericsHelper.getGenericClassAt
|
||||||
import com.appttude.h_mal.atlas_weather.model.ViewState
|
import com.appttude.h_mal.atlas_weather.model.ViewState
|
||||||
import com.appttude.h_mal.atlas_weather.utils.Event
|
|
||||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.baseViewModels.BaseViewModel
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.kodein.di.KodeinAware
|
import org.kodein.di.KodeinAware
|
||||||
import org.kodein.di.android.x.kodein
|
import org.kodein.di.android.x.kodein
|
||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
@@ -32,7 +20,7 @@ abstract class BaseFragment<V : BaseViewModel>(@LayoutRes contentLayoutId: Int)
|
|||||||
KodeinAware {
|
KodeinAware {
|
||||||
|
|
||||||
override val kodein by kodein()
|
override val kodein by kodein()
|
||||||
val factory by instance<ApplicationViewModelFactory>()
|
private val factory by instance<ApplicationViewModelFactory>()
|
||||||
|
|
||||||
val viewModel: V by getFragmentViewModel()
|
val viewModel: V by getFragmentViewModel()
|
||||||
|
|
||||||
@@ -47,7 +35,6 @@ abstract class BaseFragment<V : BaseViewModel>(@LayoutRes contentLayoutId: Int)
|
|||||||
shortAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime)
|
shortAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
mActivity = activity as BaseActivity
|
mActivity = activity as BaseActivity
|
||||||
@@ -84,53 +71,4 @@ abstract class BaseFragment<V : BaseViewModel>(@LayoutRes contentLayoutId: Int)
|
|||||||
open fun onFailure(error: Any?) {
|
open fun onFailure(error: Any?) {
|
||||||
mActivity?.onFailure(error)
|
mActivity?.onFailure(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Request a permission for
|
|
||||||
* @param permission with
|
|
||||||
* @param permissionCode
|
|
||||||
* Callback if is already permission granted
|
|
||||||
* @param permissionGranted
|
|
||||||
*/
|
|
||||||
fun getPermissionResult(
|
|
||||||
permission: String,
|
|
||||||
permissionCode: Int,
|
|
||||||
permissionGranted: () -> Unit
|
|
||||||
) {
|
|
||||||
if (ActivityCompat.checkSelfPermission(
|
|
||||||
requireContext(),
|
|
||||||
permission
|
|
||||||
) != PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
requestPermissions(arrayOf(permission), permissionCode)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
|
||||||
permissionGranted.invoke()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
|
||||||
override fun onRequestPermissionsResult(
|
|
||||||
requestCode: Int,
|
|
||||||
permissions: Array<String?>,
|
|
||||||
grantResults: IntArray
|
|
||||||
) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
|
||||||
if (requestCode == LOCATION_PERMISSION_REQUEST) {
|
|
||||||
if (grantResults.isNotEmpty() &&
|
|
||||||
grantResults[0] == PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
permissionsGranted()
|
|
||||||
displayToast("Permission granted")
|
|
||||||
} else {
|
|
||||||
permissionsRefused()
|
|
||||||
displayToast("Permission denied")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun permissionsGranted() {}
|
|
||||||
open fun permissionsRefused() {}
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.viewmodel.baseViewModels
|
package com.appttude.h_mal.atlas_weather.base.baseViewModels
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.viewmodel.baseViewModels
|
package com.appttude.h_mal.atlas_weather.base.baseViewModels
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.WeatherResponse
|
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.WeatherResponse
|
||||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||||
import com.appttude.h_mal.atlas_weather.model.weather.FullWeather
|
import com.appttude.h_mal.atlas_weather.model.weather.FullWeather
|
||||||
@@ -44,6 +44,8 @@ class PreferenceProvider(
|
|||||||
preference.edit().putBoolean("FIRST_TIME_RUN", false).apply()
|
preference.edit().putBoolean("FIRST_TIME_RUN", false).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getFirstTimeRun() = preference.getBoolean("FIRST_TIME_RUN", false)
|
||||||
|
|
||||||
fun isWidgetBackground(): Boolean {
|
fun isWidgetBackground(): Boolean {
|
||||||
return preference.getBoolean("widget_black_background", false)
|
return preference.getBoolean("widget_black_background", false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,6 @@ package com.appttude.h_mal.atlas_weather.data.repository
|
|||||||
interface SettingsRepository {
|
interface SettingsRepository {
|
||||||
fun isNotificationsEnabled(): Boolean
|
fun isNotificationsEnabled(): Boolean
|
||||||
fun setFirstTime()
|
fun setFirstTime()
|
||||||
|
fun getFirstTime(): Boolean
|
||||||
fun isBlackBackground(): Boolean
|
fun isBlackBackground(): Boolean
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ class SettingsRepositoryImpl(
|
|||||||
override fun isNotificationsEnabled(): Boolean = prefs.isNotificationsEnabled()
|
override fun isNotificationsEnabled(): Boolean = prefs.isNotificationsEnabled()
|
||||||
|
|
||||||
override fun setFirstTime() = prefs.setFirstTimeRun()
|
override fun setFirstTime() = prefs.setFirstTimeRun()
|
||||||
|
override fun getFirstTime(): Boolean = prefs.getFirstTimeRun()
|
||||||
|
|
||||||
override fun isBlackBackground() = prefs.isWidgetBackground()
|
override fun isBlackBackground() = prefs.isWidgetBackground()
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import com.appttude.h_mal.atlas_weather.data.repository.Repository
|
|||||||
import com.appttude.h_mal.atlas_weather.data.room.entity.CURRENT_LOCATION
|
import com.appttude.h_mal.atlas_weather.data.room.entity.CURRENT_LOCATION
|
||||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.baseViewModels.WeatherViewModel
|
import com.appttude.h_mal.atlas_weather.base.baseViewModels.WeatherViewModel
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import com.appttude.h_mal.atlas_weather.data.repository.Repository
|
|||||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||||
import com.appttude.h_mal.atlas_weather.model.types.LocationType
|
import com.appttude.h_mal.atlas_weather.model.types.LocationType
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.baseViewModels.WeatherViewModel
|
import com.appttude.h_mal.atlas_weather.base.baseViewModels.WeatherViewModel
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import android.view.View
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
import com.appttude.h_mal.atlas_weather.base.BaseFragment
|
||||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||||
import com.appttude.h_mal.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
import com.appttude.h_mal.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||||
|
|||||||
@@ -11,24 +11,30 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.navigation.Navigation.findNavController
|
import androidx.navigation.Navigation.findNavController
|
||||||
import androidx.navigation.ui.onNavDestinationSelected
|
import androidx.navigation.ui.onNavDestinationSelected
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
import com.appttude.h_mal.atlas_weather.base.BaseFragment
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.Forecast
|
import com.appttude.h_mal.atlas_weather.model.forecast.Forecast
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||||
|
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.MainViewModel
|
import com.appttude.h_mal.atlas_weather.viewmodel.MainViewModel
|
||||||
import com.appttude.h_mal.monoWeather.dialog.PermissionsDeclarationDialog
|
import com.appttude.h_mal.monoWeather.dialog.PermissionsDeclarationDialog
|
||||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
|
||||||
import com.appttude.h_mal.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
import com.appttude.h_mal.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||||
import kotlinx.android.synthetic.main.fragment_home.*
|
import kotlinx.android.synthetic.main.fragment_home.*
|
||||||
|
import permissions.dispatcher.NeedsPermission
|
||||||
|
import permissions.dispatcher.OnNeverAskAgain
|
||||||
|
import permissions.dispatcher.OnPermissionDenied
|
||||||
|
import permissions.dispatcher.OnShowRationale
|
||||||
|
import permissions.dispatcher.PermissionRequest
|
||||||
|
import permissions.dispatcher.RuntimePermissions
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple [Fragment] subclass.
|
* A simple [Fragment] subclass.
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
|
@RuntimePermissions
|
||||||
class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
||||||
|
|
||||||
lateinit var dialog: PermissionsDeclarationDialog
|
|
||||||
lateinit var recyclerAdapter: WeatherRecyclerAdapter
|
lateinit var recyclerAdapter: WeatherRecyclerAdapter
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
@@ -36,16 +42,12 @@ class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
|
|
||||||
dialog = PermissionsDeclarationDialog(requireContext())
|
|
||||||
|
|
||||||
swipe_refresh.apply {
|
swipe_refresh.apply {
|
||||||
setOnRefreshListener {
|
setOnRefreshListener {
|
||||||
getPermissionResult(ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
showLocationWithPermissionCheck()
|
||||||
viewModel.fetchData()
|
|
||||||
isRefreshing = true
|
isRefreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
recyclerAdapter = WeatherRecyclerAdapter(itemClick = {
|
recyclerAdapter = WeatherRecyclerAdapter(itemClick = {
|
||||||
navigateToFurtherDetails(it)
|
navigateToFurtherDetails(it)
|
||||||
@@ -57,16 +59,7 @@ class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
|||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
dialog.showDialog(agreeCallback = {
|
showLocationWithPermissionCheck()
|
||||||
getPermissionResult(ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
|
||||||
viewModel.fetchData()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
|
||||||
super.onStop()
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccess(data: Any?) {
|
override fun onSuccess(data: Any?) {
|
||||||
@@ -83,14 +76,8 @@ class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
|||||||
swipe_refresh.isRefreshing = false
|
swipe_refresh.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
|
||||||
override fun permissionsGranted() {
|
|
||||||
viewModel.fetchData()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun navigateToFurtherDetails(forecast: Forecast) {
|
private fun navigateToFurtherDetails(forecast: Forecast) {
|
||||||
val directions = HomeFragmentDirections
|
val directions = HomeFragmentDirections.actionHomeFragmentToFurtherDetailsFragment(forecast)
|
||||||
.actionHomeFragmentToFurtherDetailsFragment(forecast)
|
|
||||||
navigateTo(directions)
|
navigateTo(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,4 +90,35 @@ class HomeFragment : BaseFragment<MainViewModel>(R.layout.fragment_home) {
|
|||||||
val navController = findNavController(requireActivity(), R.id.container)
|
val navController = findNavController(requireActivity(), R.id.container)
|
||||||
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
|
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
// NOTE: delegate the permission handling to generated method
|
||||||
|
onRequestPermissionsResult(requestCode, grantResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
|
@NeedsPermission(ACCESS_COARSE_LOCATION)
|
||||||
|
fun showLocation() {
|
||||||
|
viewModel.fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnShowRationale(ACCESS_COARSE_LOCATION)
|
||||||
|
fun showRationaleForLocation(request: PermissionRequest) {
|
||||||
|
PermissionsDeclarationDialog(requireContext()).showDialog({
|
||||||
|
request.proceed()
|
||||||
|
}, {
|
||||||
|
request.cancel()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnPermissionDenied(ACCESS_COARSE_LOCATION)
|
||||||
|
fun onLocationDenied() {
|
||||||
|
displayToast("Location permissions have been denied")
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnNeverAskAgain(ACCESS_COARSE_LOCATION)
|
||||||
|
fun onLocationNeverAskAgain() {
|
||||||
|
displayToast("Location permissions have been to never ask again")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.appttude.h_mal.monoWeather.ui.widget
|
package com.appttude.h_mal.monoWeather.ui.widget
|
||||||
|
|
||||||
|
import android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
||||||
import android.Manifest.permission.ACCESS_COARSE_LOCATION
|
import android.Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||||
@@ -7,20 +8,26 @@ import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
|
|||||||
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS
|
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS
|
||||||
import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
|
import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat.checkSelfPermission
|
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||||
import com.appttude.h_mal.monoWeather.dialog.DeclarationBuilder
|
import com.appttude.h_mal.monoWeather.dialog.DeclarationBuilder
|
||||||
|
import com.appttude.h_mal.monoWeather.dialog.PermissionsDeclarationDialog
|
||||||
import kotlinx.android.synthetic.monoWeather.permissions_declaration_dialog.cancel
|
import kotlinx.android.synthetic.monoWeather.permissions_declaration_dialog.cancel
|
||||||
import kotlinx.android.synthetic.monoWeather.permissions_declaration_dialog.submit
|
import kotlinx.android.synthetic.monoWeather.permissions_declaration_dialog.submit
|
||||||
|
import permissions.dispatcher.NeedsPermission
|
||||||
|
import permissions.dispatcher.OnNeverAskAgain
|
||||||
|
import permissions.dispatcher.OnPermissionDenied
|
||||||
|
import permissions.dispatcher.OnShowRationale
|
||||||
|
import permissions.dispatcher.PermissionRequest
|
||||||
|
import permissions.dispatcher.RuntimePermissions
|
||||||
|
|
||||||
const val PERMISSION_CODE = 401
|
@RuntimePermissions
|
||||||
|
|
||||||
class WidgetLocationPermissionActivity : AppCompatActivity(), DeclarationBuilder {
|
class WidgetLocationPermissionActivity : AppCompatActivity(), DeclarationBuilder {
|
||||||
override val link: String = "https://sites.google.com/view/hmaldev/home/monochrome"
|
override val link: String = "https://sites.google.com/view/hmaldev/home/monochrome"
|
||||||
override var message: String = ""
|
override var message: String = ""
|
||||||
@@ -54,31 +61,16 @@ class WidgetLocationPermissionActivity : AppCompatActivity(), DeclarationBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
submit.setOnClickListener {
|
submit.setOnClickListener {
|
||||||
if (checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PERMISSION_GRANTED) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
requestPermissions(arrayOf(ACCESS_COARSE_LOCATION), PERMISSION_CODE)
|
showBackgroundLocationWithPermissionCheck()
|
||||||
} else {
|
} else {
|
||||||
submitWidget()
|
showLocationWithPermissionCheck()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel.setOnClickListener { finish() }
|
cancel.setOnClickListener { finish() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(
|
|
||||||
requestCode: Int,
|
|
||||||
permissions: Array<out String>,
|
|
||||||
grantResults: IntArray
|
|
||||||
) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
|
||||||
if (requestCode == PERMISSION_CODE) {
|
|
||||||
if (grantResults.isNotEmpty() && grantResults[0] == PERMISSION_GRANTED) {
|
|
||||||
submitWidget()
|
|
||||||
} else {
|
|
||||||
displayToast("Location Permission denied")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun submitWidget() {
|
private fun submitWidget() {
|
||||||
sendUpdateIntent()
|
sendUpdateIntent()
|
||||||
finishCurrencyWidgetActivity()
|
finishCurrencyWidgetActivity()
|
||||||
@@ -106,4 +98,66 @@ class WidgetLocationPermissionActivity : AppCompatActivity(), DeclarationBuilder
|
|||||||
sendBroadcast(this)
|
sendBroadcast(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
// NOTE: delegate the permission handling to generated method
|
||||||
|
onRequestPermissionsResult(requestCode, grantResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
@NeedsPermission(ACCESS_COARSE_LOCATION)
|
||||||
|
fun showLocation() {
|
||||||
|
submitWidget()
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@NeedsPermission(ACCESS_BACKGROUND_LOCATION)
|
||||||
|
fun showBackgroundLocation() {
|
||||||
|
submitWidget()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnShowRationale(ACCESS_COARSE_LOCATION)
|
||||||
|
fun showRationaleForLocation(request: PermissionRequest) {
|
||||||
|
PermissionsDeclarationDialog(this).showDialog({
|
||||||
|
request.proceed()
|
||||||
|
}, {
|
||||||
|
request.cancel()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@OnShowRationale(ACCESS_BACKGROUND_LOCATION)
|
||||||
|
fun showRationaleForBackgroundLocation(request: PermissionRequest) {
|
||||||
|
PermissionsDeclarationDialog(this).showDialog({
|
||||||
|
request.proceed()
|
||||||
|
}, {
|
||||||
|
request.cancel()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnPermissionDenied(ACCESS_COARSE_LOCATION)
|
||||||
|
fun onLocationDenied() {
|
||||||
|
displayToast("Location permissions have been denied")
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@OnPermissionDenied(ACCESS_BACKGROUND_LOCATION)
|
||||||
|
fun onBackgroundLocationDenied() {
|
||||||
|
displayToast("Background Location permissions have been denied")
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnNeverAskAgain(ACCESS_COARSE_LOCATION)
|
||||||
|
fun onLocationNeverAskAgain() {
|
||||||
|
displayToast("Location permissions have been to never ask again")
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@OnNeverAskAgain(ACCESS_BACKGROUND_LOCATION)
|
||||||
|
fun onBackgroundLocationNeverAskAgain() {
|
||||||
|
displayToast("Background Location permissions have been to never ask again")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ package com.appttude.h_mal.monoWeather.ui.world
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
import com.appttude.h_mal.atlas_weather.base.BaseFragment
|
||||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||||
import com.appttude.h_mal.atlas_weather.utils.goBack
|
import com.appttude.h_mal.atlas_weather.utils.goBack
|
||||||
import com.appttude.h_mal.atlas_weather.utils.hideKeyboard
|
import com.appttude.h_mal.atlas_weather.utils.hideKeyboard
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
import com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay
|
||||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
import com.appttude.h_mal.atlas_weather.base.BaseFragment
|
||||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||||
import com.appttude.h_mal.monoWeather.ui.world.WorldFragmentDirections.actionWorldFragmentToWorldItemFragment
|
import com.appttude.h_mal.monoWeather.ui.world.WorldFragmentDirections.actionWorldFragmentToWorldItemFragment
|
||||||
|
|||||||
13
app/src/monoWeather/res/xml-v31/new_app_widget_info.xml
Normal file
13
app/src/monoWeather/res/xml-v31/new_app_widget_info.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:configure="com.appttude.h_mal.monoWeather.ui.widget.WidgetLocationPermissionActivity"
|
||||||
|
android:initialKeyguardLayout="@layout/weather_app_widget"
|
||||||
|
android:initialLayout="@layout/weather_app_widget"
|
||||||
|
android:targetCellWidth="5"
|
||||||
|
android:targetCellHeight="1"
|
||||||
|
android:previewImage="@drawable/widget_screenshot"
|
||||||
|
android:resizeMode="vertical|horizontal"
|
||||||
|
android:updatePeriodMillis="1800000"
|
||||||
|
android:widgetCategory="home_screen">
|
||||||
|
|
||||||
|
</appwidget-provider>
|
||||||
Reference in New Issue
Block a user