mirror of
https://github.com/hmalik144/Weather-apps.git
synced 2025-12-10 02:05:20 +00:00
Flavours fixed
UI tests fixed fastlane added
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@@ -88,3 +88,11 @@ gen-external-apklibs
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/gradle.xml
|
||||
.idea/jarRepositorie
|
||||
|
||||
# Gem/fastlane
|
||||
/Gemfile.lock
|
||||
/fastlane/report.xml
|
||||
# Google play files
|
||||
/google-play-key.json
|
||||
|
||||
/.idea/androidTestResultsUserPreferences.xml
|
||||
|
||||
24
.idea/codeStyles/Project.xml
generated
24
.idea/codeStyles/Project.xml
generated
@@ -1,24 +1,13 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value>
|
||||
<package name="java.util" alias="false" withSubpackages="false" />
|
||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="java" alias="false" withSubpackages="true" />
|
||||
<package name="javax" alias="false" withSubpackages="true" />
|
||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
@@ -127,5 +116,8 @@
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
6
.idea/kotlinc.xml
generated
Normal file
6
.idea/kotlinc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="1.6.0" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,9 +1,9 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'kotlin-android-extensions'
|
||||
id 'kotlin-kapt'
|
||||
id 'androidx.navigation.safeargs'
|
||||
id 'kotlin-parcelize'
|
||||
}
|
||||
android {
|
||||
lintOptions {
|
||||
@@ -11,12 +11,12 @@ android {
|
||||
}
|
||||
compileSdkVersion 33
|
||||
defaultConfig {
|
||||
applicationId "com.appttude.h_mal"
|
||||
applicationId "com.appttude.h_mal.atlas_weather"
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 33
|
||||
versionCode 5
|
||||
versionName "3.0"
|
||||
testInstrumentationRunner "com.appttude.h_mal.application.TestRunner"
|
||||
testInstrumentationRunner "com.appttude.h_mal.atlas_weather.application.TestRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
Properties properties = new Properties()
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.appttude.h_mal.atlas_weather
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.espresso.internal.inject.InstrumentationContext
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import com.appttude.h_mal.atlas_weather.application.TestAppClass
|
||||
import com.appttude.h_mal.atlas_weather.helper.GenericsHelper.getGenericClassAt
|
||||
import com.appttude.h_mal.atlas_weather.helpers.SnapshotRule
|
||||
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import tools.fastlane.screengrab.Screengrab
|
||||
import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy
|
||||
|
||||
open class BaseTest<A : Activity>(
|
||||
private val activity: Class<A>,
|
||||
private val intentBundle: Bundle? = null,
|
||||
) {
|
||||
|
||||
lateinit var scenario: ActivityScenario<A>
|
||||
private lateinit var testApp: TestAppClass
|
||||
|
||||
@get:Rule
|
||||
var permissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
|
||||
@get:Rule
|
||||
var snapshotRule: SnapshotRule = SnapshotRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy())
|
||||
val startIntent = Intent(InstrumentationRegistry.getInstrumentation().targetContext, activity)
|
||||
if (intentBundle != null) {
|
||||
startIntent.replaceExtras(intentBundle)
|
||||
}
|
||||
|
||||
scenario = ActivityScenario.launch(startIntent)
|
||||
scenario.onActivity {
|
||||
runBlocking {
|
||||
testApp = it.application as TestAppClass
|
||||
beforeLaunch()
|
||||
}
|
||||
}
|
||||
afterLaunch()
|
||||
}
|
||||
|
||||
fun stubEndpoint(url: String, stub: Stubs) {
|
||||
testApp.stubUrl(url, stub.id)
|
||||
}
|
||||
|
||||
fun unstubEndpoint(url: String) {
|
||||
testApp.removeUrlStub(url)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
testFinished()
|
||||
}
|
||||
|
||||
open fun beforeLaunch() {}
|
||||
open fun afterLaunch() {}
|
||||
open fun testFinished() {}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.utils
|
||||
package com.appttude.h_mal.atlas_weather
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.view.View
|
||||
@@ -16,14 +16,9 @@ import androidx.test.espresso.action.ViewActions.swipeDown
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.contrib.PickerActions
|
||||
import androidx.test.espresso.contrib.RecyclerViewActions
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withClassName
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import com.appttude.h_mal.atlas_weather.checkErrorMessage
|
||||
import com.appttude.h_mal.atlas_weather.checkImage
|
||||
import androidx.test.espresso.matcher.ViewMatchers.*
|
||||
import com.appttude.h_mal.atlas_weather.helpers.checkErrorMessage
|
||||
import com.appttude.h_mal.atlas_weather.helpers.checkImage
|
||||
import com.appttude.h_mal.atlas_weather.helpers.EspressoHelper.waitForView
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.CoreMatchers.anything
|
||||
@@ -46,6 +41,8 @@ open class BaseTestRobot {
|
||||
|
||||
fun matchViewWaitFor(resId: Int): ViewInteraction = waitForView(withId(resId))
|
||||
|
||||
fun matchDisplayed(resId: Int): ViewInteraction = matchView(resId).check(matches(isDisplayed()))
|
||||
|
||||
fun matchText(viewInteraction: ViewInteraction, text: String): ViewInteraction = viewInteraction
|
||||
.check(matches(withText(text)))
|
||||
|
||||
@@ -142,7 +139,7 @@ open class BaseTestRobot {
|
||||
Resources.getSystem().getString(resId)
|
||||
|
||||
fun pullToRefresh(resId: Int){
|
||||
onView(allOf(withId(resId), ViewMatchers.isDisplayed())).perform(swipeDown())
|
||||
onView(allOf(withId(resId), isDisplayed())).perform(swipeDown())
|
||||
}
|
||||
|
||||
fun selectDateInPicker(year: Int, month: Int, day: Int) {
|
||||
@@ -1,141 +0,0 @@
|
||||
//package com.appttude.h_mal.atlas_weather
|
||||
//
|
||||
//import android.Manifest
|
||||
//import android.R
|
||||
//import android.app.Activity
|
||||
//import android.content.Context
|
||||
//import android.os.Build
|
||||
//import android.view.View
|
||||
//import android.view.WindowManager
|
||||
//import androidx.annotation.StringRes
|
||||
//import androidx.test.core.app.ActivityScenario
|
||||
//import androidx.test.espresso.*
|
||||
//import androidx.test.espresso.Espresso.onView
|
||||
//import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
//import androidx.test.espresso.matcher.ViewMatchers.*
|
||||
//import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||
//import androidx.test.rule.GrantPermissionRule
|
||||
//import com.appttude.h_mal.atlas_weather.atlasWeather.ui.BaseActivity
|
||||
////import h_mal.appttude.com.driver.base.BaseActivity
|
||||
//import com.appttude.h_mal.atlas_weather.helpers.BaseViewAction
|
||||
//import com.appttude.h_mal.atlas_weather.helpers.SnapshotRule
|
||||
//import org.hamcrest.CoreMatchers
|
||||
//import org.hamcrest.Description
|
||||
//import org.hamcrest.Matcher
|
||||
//import org.hamcrest.TypeSafeMatcher
|
||||
//import org.hamcrest.core.AllOf
|
||||
//import org.junit.After
|
||||
//import org.junit.Before
|
||||
//import org.junit.Rule
|
||||
//import tools.fastlane.screengrab.Screengrab
|
||||
//import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy
|
||||
//import tools.fastlane.screengrab.locale.LocaleTestRule
|
||||
//
|
||||
//
|
||||
//open class BaseUiTest<T : BaseActivity>(
|
||||
// private val activity: Class<T>
|
||||
//) {
|
||||
//
|
||||
// private lateinit var mActivityScenarioRule: ActivityScenario<T>
|
||||
// private var mIdlingResource: IdlingResource? = null
|
||||
//
|
||||
// private lateinit var currentActivity: Activity
|
||||
//
|
||||
// @get:Rule
|
||||
// var permissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
//
|
||||
// @get:Rule
|
||||
// var snapshotRule: SnapshotRule = SnapshotRule()
|
||||
//
|
||||
// @Rule
|
||||
// @JvmField
|
||||
// var localeTestRule = LocaleTestRule()
|
||||
//
|
||||
// @Before
|
||||
// fun setup() {
|
||||
// Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy())
|
||||
// beforeLaunch()
|
||||
// mActivityScenarioRule = ActivityScenario.launch(activity)
|
||||
// mActivityScenarioRule.onActivity {
|
||||
//// mIdlingResource = it.getIdlingResource()!!
|
||||
//// IdlingRegistry.getInstance().register(mIdlingResource)
|
||||
// afterLaunch(it)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @After
|
||||
// fun tearDown() {
|
||||
// mIdlingResource?.let {
|
||||
// IdlingRegistry.getInstance().unregister(it)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun getResourceString(@StringRes stringRes: Int): String {
|
||||
// return getInstrumentation().targetContext.resources.getString(
|
||||
// stringRes
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// fun waitFor(delay: Long) {
|
||||
// onView(isRoot()).perform(object : ViewAction {
|
||||
// override fun getConstraints(): Matcher<View> = isRoot()
|
||||
// override fun getDescription(): String = "wait for $delay milliseconds"
|
||||
// override fun perform(uiController: UiController, v: View?) {
|
||||
// uiController.loopMainThreadForAtLeast(delay)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// open fun beforeLaunch() {}
|
||||
// open fun afterLaunch(context: Context) {}
|
||||
//
|
||||
//
|
||||
// @Suppress("DEPRECATION")
|
||||
// fun checkToastMessage(message: String) {
|
||||
// onView(withText(message)).inRoot(object : TypeSafeMatcher<Root>() {
|
||||
// override fun describeTo(description: Description?) {
|
||||
// description?.appendText("is toast")
|
||||
// }
|
||||
//
|
||||
// override fun matchesSafely(root: Root): Boolean {
|
||||
// root.run {
|
||||
// if (windowLayoutParams.get().type == WindowManager.LayoutParams.TYPE_TOAST) {
|
||||
// decorView.run {
|
||||
// if (windowToken === applicationWindowToken) {
|
||||
// // windowToken == appToken means this window isn't contained by any other windows.
|
||||
// // if it was a window for an activity, it would have TYPE_BASE_APPLICATION.
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// ).check(matches(isDisplayed()))
|
||||
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||
// waitFor(3500)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun checkSnackBarDisplayedByMessage(message: String) {
|
||||
// onView(
|
||||
// CoreMatchers.allOf(
|
||||
// withId(com.google.android.material.R.id.snackbar_text),
|
||||
// withText(message)
|
||||
// )
|
||||
// ).check(matches(isDisplayed()))
|
||||
// }
|
||||
//
|
||||
// private fun getCurrentActivity(): Activity {
|
||||
// onView(AllOf.allOf(withId(R.id.content), isDisplayed()))
|
||||
// .perform(object : BaseViewAction() {
|
||||
// override fun setPerform(uiController: UiController?, view: View?) {
|
||||
// if (view?.context is Activity) {
|
||||
// currentActivity = view.context as Activity
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// return currentActivity
|
||||
// }
|
||||
//}
|
||||
@@ -4,6 +4,7 @@ package com.appttude.h_mal.atlas_weather.data.location
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProviderImpl
|
||||
import com.appttude.h_mal.atlas_weather.model.types.LocationType
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.hamcrest.Matcher.*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.appttude.h_mal.atlas_weather.data.location
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
||||
import com.appttude.h_mal.atlas_weather.model.types.LocationType
|
||||
|
||||
class MockLocationProvider : LocationProvider {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.helpers
|
||||
|
||||
import android.os.Environment
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* File paths for images on device
|
||||
*/
|
||||
fun getImagePath(imageConst: String): String {
|
||||
return File(
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
|
||||
"/Camera/images/$imageConst"
|
||||
).absolutePath
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather
|
||||
package com.appttude.h_mal.atlas_weather.helpers
|
||||
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.view.View
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.helpers
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipData.Item
|
||||
import android.net.Uri
|
||||
import java.io.File
|
||||
|
||||
object DataHelper {
|
||||
|
||||
fun createClipItem(filePath: String) = Item(
|
||||
Uri.fromFile(
|
||||
File(filePath)
|
||||
)
|
||||
)
|
||||
|
||||
fun createClipData(item: Item, mimeType: String = "text/uri-list") =
|
||||
ClipData(null, arrayOf(mimeType), item)
|
||||
|
||||
fun createClipData(filePath: String) = createClipData(createClipItem(filePath))
|
||||
|
||||
fun createClipData(filePaths: Array<String>): ClipData {
|
||||
val clipData = createClipData(filePaths[0])
|
||||
val remainingFiles = filePaths.copyOfRange(1, filePaths.size - 1)
|
||||
clipData.addFilePaths(remainingFiles)
|
||||
return clipData
|
||||
}
|
||||
|
||||
fun createClipData(uri: Uri) = createClipData(Item(uri))
|
||||
|
||||
fun ClipData.addFilePaths(filePaths: Array<String>) {
|
||||
filePaths.forEach { addItem(createClipItem(it)) }
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.testsuite
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.RootMatchers.isDialog
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import com.appttude.h_mal.atlas_weather.application.TestAppClass
|
||||
import com.appttude.h_mal.atlas_weather.helper.GenericsHelper.getGenericClassAt
|
||||
import com.appttude.h_mal.atlas_weather.helpers.SnapshotRule
|
||||
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||
import org.junit.After
|
||||
import org.junit.Rule
|
||||
import tools.fastlane.screengrab.Screengrab
|
||||
import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy
|
||||
|
||||
open class BaseTest<A : Activity> {
|
||||
|
||||
lateinit var testApp: TestAppClass
|
||||
|
||||
@get:Rule
|
||||
var permissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
|
||||
@get:Rule
|
||||
var snapshotRule: SnapshotRule = SnapshotRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
var mActivityTestRule: ActivityTestRule<A> =
|
||||
object : ActivityTestRule<A>(getGenericClassAt<A>(0).java) {
|
||||
override fun beforeActivityLaunched() {
|
||||
super.beforeActivityLaunched()
|
||||
Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy())
|
||||
|
||||
testApp =
|
||||
InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as TestAppClass
|
||||
setupFeed()
|
||||
}
|
||||
|
||||
override fun afterActivityLaunched() {
|
||||
|
||||
// Dismiss dialog
|
||||
onView(withText("AGREE")).inRoot(isDialog()).check(matches(isDisplayed()))
|
||||
.perform(ViewActions.click())
|
||||
}
|
||||
}
|
||||
|
||||
fun stubEndpoint(url: String, stub: Stubs) {
|
||||
testApp.stubUrl(url, stub.id)
|
||||
}
|
||||
|
||||
fun unstubEndpoint(url: String) {
|
||||
testApp.removeUrlStub(url)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
}
|
||||
|
||||
open fun setupFeed() {}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.testsuite
|
||||
|
||||
|
||||
import android.Manifest
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.core.app.ActivityScenario.launch
|
||||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.assertion.ViewAssertions
|
||||
import androidx.test.espresso.matcher.RootMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import com.appttude.h_mal.atlas_weather.application.TestAppClass
|
||||
import com.appttude.h_mal.atlas_weather.robot.homeScreen
|
||||
import com.appttude.h_mal.atlas_weather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4ClassRunner::class)
|
||||
class HomePageUITestScenario : BaseMainScenario() {
|
||||
|
||||
override fun setupFeed() {
|
||||
stubEndpoint("https://api.openweathermap.org/data/2.5/onecall", Stubs.Valid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun loadApp_validWeatherResponse_returnsValidPage() {
|
||||
homeScreen {
|
||||
verifyCurrentTemperature(2)
|
||||
verifyCurrentLocation("Mock Location")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class BaseMainScenario {
|
||||
|
||||
lateinit var scenario: ActivityScenario<MainActivity>
|
||||
private lateinit var testApp: TestAppClass
|
||||
|
||||
@get:Rule
|
||||
var permissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
scenario = launch(MainActivity::class.java)
|
||||
scenario.onActivity {
|
||||
runBlocking {
|
||||
testApp = it.application as TestAppClass
|
||||
setupFeed()
|
||||
}
|
||||
}
|
||||
|
||||
// Dismiss dialog on start up
|
||||
Espresso.onView(ViewMatchers.withText("AGREE"))
|
||||
.inRoot(RootMatchers.isDialog())
|
||||
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
|
||||
.perform(ViewActions.click())
|
||||
}
|
||||
|
||||
fun stubEndpoint(url: String, stub: Stubs) {
|
||||
testApp.stubUrl(url, stub.id)
|
||||
}
|
||||
|
||||
fun unstubEndpoint(url: String) {
|
||||
testApp.removeUrlStub(url)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
testFinished()
|
||||
}
|
||||
|
||||
open fun setupFeed() {}
|
||||
open fun testFinished() {}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.ui.widget
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Intent
|
||||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
|
||||
class WidgetLocationPermissionActivityTest {
|
||||
@Rule
|
||||
@JvmField
|
||||
var mActivityTestRule : ActivityTestRule<WidgetLocationPermissionActivity> =
|
||||
ActivityTestRule(WidgetLocationPermissionActivity::class.java, false, false)
|
||||
|
||||
@Test
|
||||
fun demo_test() {
|
||||
val startIntent = Intent().apply {
|
||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 112)
|
||||
}
|
||||
mActivityTestRule.launchActivity(startIntent)
|
||||
|
||||
Espresso.onView((ViewMatchers.withId(R.id.declaration_text))).check(matches(isDisplayed()));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.appttude.h_mal.atlas_weather.robot
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.BaseTestRobot
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.utils.BaseTestRobot
|
||||
|
||||
fun homeScreen(func: HomeScreenRobot.() -> Unit) = HomeScreenRobot().apply { func() }
|
||||
class HomeScreenRobot : BaseTestRobot() {
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
package com.appttude.h_mal.atlas_weather.tests
|
||||
|
||||
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.BaseTest
|
||||
import com.appttude.h_mal.atlas_weather.robot.homeScreen
|
||||
import com.appttude.h_mal.atlas_weather.testsuite.BaseTest
|
||||
import com.appttude.h_mal.atlas_weather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class HomePageUITest : BaseTest<MainActivity>() {
|
||||
class HomePageUITest : BaseTest<MainActivity>(activity = MainActivity::class.java) {
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
var mGrantPermissionRule: GrantPermissionRule =
|
||||
GrantPermissionRule.grant(
|
||||
"android.permission.ACCESS_COARSE_LOCATION")
|
||||
|
||||
override fun setupFeed() {
|
||||
override fun beforeLaunch() {
|
||||
stubEndpoint("https://api.openweathermap.org/data/2.5/onecall", Stubs.Valid)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.appttude.h_mal.monoWeather
|
||||
|
||||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.assertion.ViewAssertions
|
||||
import androidx.test.espresso.matcher.RootMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import com.appttude.h_mal.atlas_weather.BaseTest
|
||||
import com.appttude.h_mal.atlas_weather.ui.MainActivity
|
||||
|
||||
open class MonoBaseTest: BaseTest<MainActivity>(MainActivity::class.java) {
|
||||
|
||||
override fun afterLaunch() {
|
||||
// Dismiss dialog on start up
|
||||
Espresso.onView(ViewMatchers.withText("AGREE"))
|
||||
.inRoot(RootMatchers.isDialog())
|
||||
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
|
||||
.perform(ViewActions.click())
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.appttude.h_mal.atlas_weather.robot
|
||||
package com.appttude.h_mal.monoWeather.robot
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.utils.BaseTestRobot
|
||||
import com.appttude.h_mal.atlas_weather.BaseTestRobot
|
||||
|
||||
fun homeScreen(func: HomeScreenRobot.() -> Unit) = HomeScreenRobot().apply { func() }
|
||||
class HomeScreenRobot : BaseTestRobot() {
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.appttude.h_mal.monoWeather.robot
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.BaseTestRobot
|
||||
|
||||
fun widgetPermissionScreen(func: WidgetPermissionScreenRobot.() -> Unit) =
|
||||
WidgetPermissionScreenRobot().apply { func() }
|
||||
|
||||
class WidgetPermissionScreenRobot : BaseTestRobot() {
|
||||
fun declarationDisplayed() = matchDisplayed(R.id.declaration_text)
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
package com.appttude.h_mal.atlas_weather.tests
|
||||
package com.appttude.h_mal.monoWeather.tests
|
||||
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.robot.homeScreen
|
||||
import com.appttude.h_mal.atlas_weather.testsuite.BaseTest
|
||||
import com.appttude.h_mal.atlas_weather.ui.MainActivity
|
||||
import com.appttude.h_mal.monoWeather.robot.homeScreen
|
||||
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||
import com.appttude.h_mal.monoWeather.MonoBaseTest
|
||||
import org.junit.Test
|
||||
|
||||
class HomePageUITest : BaseTest<MainActivity>() {
|
||||
class HomePageUITest : MonoBaseTest() {
|
||||
|
||||
override fun setupFeed() {
|
||||
override fun beforeLaunch() {
|
||||
stubEndpoint("https://api.openweathermap.org/data/2.5/onecall", Stubs.Valid)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.appttude.h_mal.monoWeather.tests
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import com.appttude.h_mal.atlas_weather.BaseTest
|
||||
import com.appttude.h_mal.monoWeather.robot.widgetPermissionScreen
|
||||
import com.appttude.h_mal.monoWeather.ui.widget.WidgetLocationPermissionActivity
|
||||
import org.junit.Test
|
||||
|
||||
|
||||
class WidgetLocationPermissionActivityTest : BaseTest<WidgetLocationPermissionActivity>(
|
||||
activity = WidgetLocationPermissionActivity::class.java,
|
||||
intentBundle = Bundle().apply {
|
||||
putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, 112)
|
||||
}
|
||||
) {
|
||||
|
||||
@Test
|
||||
fun demo_test() {
|
||||
widgetPermissionScreen {
|
||||
declarationDisplayed()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
tools:node="merge">
|
||||
|
||||
<application
|
||||
android:name="com.appttude.h_mal.application.AppClass"
|
||||
android:name="com.appttude.h_mal.atlas_weather.application.AppClass"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
@@ -26,18 +26,12 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".atlasWeather.ui.settings.UnitSettingsActivity"
|
||||
android:label="Settings"
|
||||
android:exported="true"/>
|
||||
|
||||
<receiver
|
||||
android:name=".atlasWeather.notification.NotificationReceiver"
|
||||
android:name=".notification.NotificationReceiver"
|
||||
android:parentActivityName=".MainActivity"
|
||||
android:exported="true"/>
|
||||
|
||||
<receiver android:name=".atlasWeather.widget.NewAppWidget"
|
||||
<receiver android:name=".widget.NewAppWidget"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
@@ -49,11 +43,6 @@
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/new_app_widget_info" />
|
||||
</receiver>
|
||||
|
||||
|
||||
<service
|
||||
android:name=".atlasWeather.widget.WidgetRemoteViewsService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.notification
|
||||
package com.appttude.h_mal.atlas_weather.notification
|
||||
|
||||
import android.graphics.Bitmap
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.notification
|
||||
package com.appttude.h_mal.atlas_weather.notification
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Notification
|
||||
@@ -12,13 +12,10 @@ import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.core.app.ActivityCompat
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.helper.ServicesHelper
|
||||
import com.appttude.h_mal.atlas_weather.model.weather.FullWeather
|
||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.LateInitKodein
|
||||
import org.kodein.di.generic.instance
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui
|
||||
package com.appttude.h_mal.atlas_weather.ui
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui
|
||||
package com.appttude.h_mal.atlas_weather.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.PackageManager
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.appttude.h_mal.atlas_weather.ui
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
|
||||
val tabs = setOf(R.id.nav_home, R.id.nav_world)
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui
|
||||
package com.appttude.h_mal.atlas_weather.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -8,7 +8,7 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
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.atlasWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.details
|
||||
package com.appttude.h_mal.atlas_weather.ui.details
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home
|
||||
package com.appttude.h_mal.atlas_weather.ui.home
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
@@ -13,8 +13,8 @@ import androidx.lifecycle.observe
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
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.atlasWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
||||
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.viewmodel.ApplicationViewModelFactory
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.adapter
|
||||
package com.appttude.h_mal.atlas_weather.ui.home.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.View
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.appttude.h_mal.atlas_weather.ui.settings
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.notification.NotificationReceiver
|
||||
import com.appttude.h_mal.atlas_weather.widget.NewAppWidget
|
||||
import java.util.Calendar
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.prefs, rootKey)
|
||||
|
||||
//listener on changed sort order preference:
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
prefs.registerOnSharedPreferenceChangeListener { _, key ->
|
||||
if (key == "temp_units") {
|
||||
val intent = Intent(requireContext(), NewAppWidget::class.java)
|
||||
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
val ids = AppWidgetManager.getInstance(requireContext())
|
||||
.getAppWidgetIds(ComponentName(requireContext(), NewAppWidget::class.java))
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
|
||||
requireContext().sendBroadcast(intent)
|
||||
}
|
||||
if (key == "notif_boolean") {
|
||||
setupNotificationBroadcaster(requireContext())
|
||||
}
|
||||
|
||||
if (key == "widget_black_background"){
|
||||
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
|
||||
val widgetManager = AppWidgetManager.getInstance(requireContext())
|
||||
val ids =
|
||||
widgetManager.getAppWidgetIds(ComponentName(requireContext(), NewAppWidget::class.java))
|
||||
AppWidgetManager.getInstance(requireContext())
|
||||
.notifyAppWidgetViewDataChanged(ids, R.id.whole_widget_view)
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
|
||||
requireContext().sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setupNotificationBroadcaster(context: Context) {
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val notificationIntent = Intent(context, NotificationReceiver::class.java)
|
||||
val broadcast = PendingIntent.getBroadcast(context, 100, notificationIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
val cal: Calendar = Calendar.getInstance()
|
||||
cal.set(Calendar.HOUR_OF_DAY, 6)
|
||||
cal.set(Calendar.MINUTE, 8)
|
||||
cal.set(Calendar.SECOND, 5)
|
||||
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.timeInMillis, AlarmManager.INTERVAL_DAY, broadcast)
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.settings
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceActivity
|
||||
import android.preference.PreferenceFragment
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.notification.NotificationReceiver
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.widget.NewAppWidget
|
||||
import java.util.*
|
||||
|
||||
|
||||
class UnitSettingsActivity : PreferenceActivity() {
|
||||
private var prefListener: OnSharedPreferenceChangeListener? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
PreferenceManager.setDefaultValues(this, R.xml.prefs, false)
|
||||
fragmentManager.beginTransaction().replace(android.R.id.content, MyPreferenceFragment()).commit()
|
||||
|
||||
//listener on changed sort order preference:
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||
prefListener = OnSharedPreferenceChangeListener { _, key ->
|
||||
if (key == "temp_units") {
|
||||
val intent = Intent(baseContext, NewAppWidget::class.java)
|
||||
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
val ids = AppWidgetManager.getInstance(application).getAppWidgetIds(ComponentName(application, NewAppWidget::class.java))
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
if (key == "notif_boolean") {
|
||||
setupNotificationBroadcaster(baseContext)
|
||||
}
|
||||
|
||||
if (key == "widget_black_background"){
|
||||
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
|
||||
val widgetManager = AppWidgetManager.getInstance(this)
|
||||
val ids = widgetManager.getAppWidgetIds(ComponentName(this, NewAppWidget::class.java))
|
||||
AppWidgetManager.getInstance(this).notifyAppWidgetViewDataChanged(ids, R.id.whole_widget_view)
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
prefs.registerOnSharedPreferenceChangeListener(prefListener)
|
||||
}
|
||||
|
||||
fun setupNotificationBroadcaster(context: Context) {
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val notificationIntent = Intent(context, NotificationReceiver::class.java)
|
||||
val broadcast = PendingIntent.getBroadcast(context, 100, notificationIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
val cal: Calendar = Calendar.getInstance()
|
||||
cal.set(Calendar.HOUR_OF_DAY, 6)
|
||||
cal.set(Calendar.MINUTE, 8)
|
||||
cal.set(Calendar.SECOND, 5)
|
||||
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.timeInMillis, AlarmManager.INTERVAL_DAY, broadcast)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
|
||||
// Log.i(TAG, "onSharedPreferenceChanged: " + s);
|
||||
// if (s == "temp_units"){
|
||||
// Intent intent = new Intent(getBaseContext(), NewAppWidget.class);
|
||||
// intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||
//
|
||||
// int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), NewAppWidget.class));
|
||||
// intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
|
||||
// sendBroadcast(intent);
|
||||
// }
|
||||
// }
|
||||
class MyPreferenceFragment : PreferenceFragment() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
addPreferencesFromResource(R.xml.prefs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.world
|
||||
package com.appttude.h_mal.atlas_weather.ui.world
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -7,7 +7,7 @@ import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.observe
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
||||
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.viewmodel.ApplicationViewModelFactory
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.world
|
||||
package com.appttude.h_mal.atlas_weather.ui.world
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -9,9 +9,9 @@ import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.world.WorldRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.world.WorldFragmentDirections
|
||||
import com.appttude.h_mal.atlas_weather.ui.world.WorldRecyclerAdapter
|
||||
import com.appttude.h_mal.atlas_weather.ui.BaseFragment
|
||||
import com.appttude.h_mal.atlas_weather.ui.world.WorldFragmentDirections
|
||||
import com.appttude.h_mal.atlas_weather.utils.navigateTo
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.ui.world
|
||||
package com.appttude.h_mal.atlas_weather.ui.world
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.TaskStackBuilder
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViews
|
||||
import androidx.annotation.LayoutRes
|
||||
|
||||
abstract class BaseWidgetClass : AppWidgetProvider(){
|
||||
|
||||
fun createRemoteView(context: Context, @LayoutRes id: Int): RemoteViews {
|
||||
return RemoteViews(context.packageName, id)
|
||||
}
|
||||
|
||||
fun AppWidgetProvider.createUpdatePendingIntent(context: Context, appWidgetId: Int): PendingIntent? {
|
||||
val seconds = (System.currentTimeMillis() / 1000L).toInt()
|
||||
val intentUpdate = Intent(context, this::class.java)
|
||||
intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
val idArray = intArrayOf(appWidgetId)
|
||||
intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray)
|
||||
|
||||
return PendingIntent.getBroadcast(
|
||||
context, seconds, intentUpdate,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
fun <T: Activity> createClickingPendingIntent(context: Context, activityClass: Class<T>): PendingIntent {
|
||||
val clickIntentTemplate = Intent(context, activityClass)
|
||||
|
||||
return TaskStackBuilder.create(context)
|
||||
.addNextIntentWithParentStack(clickIntentTemplate)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViews
|
||||
import android.widget.RemoteViewsService.RemoteViewsFactory
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.helper.ServicesHelper
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.InnerWidgetData
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.LateInitKodein
|
||||
import org.kodein.di.generic.instance
|
||||
|
||||
|
||||
class MyWidgetRemoteViewsFactory(
|
||||
private val context: Context,
|
||||
val intent: Intent
|
||||
) : RemoteViewsFactory{
|
||||
private val TAG = "MyWidgetRemoteViewsFactory"
|
||||
|
||||
private val kodein = LateInitKodein()
|
||||
private val helper : ServicesHelper by kodein.instance()
|
||||
|
||||
private var appWidgetId: Int? = 0
|
||||
private var list: List<InnerWidgetData>? = null
|
||||
|
||||
init {
|
||||
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID)
|
||||
kodein.baseKodein = (context.applicationContext as KodeinAware).kodein
|
||||
|
||||
}
|
||||
|
||||
override fun onCreate() {}
|
||||
override fun onDataSetChanged() {
|
||||
runBlocking {
|
||||
list = helper.getWidgetInnerWeather()
|
||||
}
|
||||
}
|
||||
override fun onDestroy() {}
|
||||
|
||||
override fun getCount(): Int = list?.size ?: 5
|
||||
|
||||
override fun getViewAt(i: Int): RemoteViews {
|
||||
val rv = RemoteViews(context.packageName, R.layout.widget_item)
|
||||
|
||||
if (list.isNullOrEmpty()) return rv
|
||||
|
||||
|
||||
list?.get(i)?.let {
|
||||
rv.setTextViewText(R.id.widget_item_day, it.date)
|
||||
rv.setImageViewBitmap(R.id.widget_item_image, it.icon)
|
||||
rv.setTextViewText(R.id.widget_item_temp_high, it.highTemp)
|
||||
rv.setOnClickFillInIntent(R.id.widget_item_layout, intent)
|
||||
}
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
override fun getLoadingView(): RemoteViews {
|
||||
return RemoteViews(context.packageName, R.layout.widget_item_loading)
|
||||
}
|
||||
|
||||
override fun getViewTypeCount(): Int = 1
|
||||
|
||||
|
||||
override fun getItemId(i: Int): Long = i.toLong()
|
||||
|
||||
|
||||
override fun hasStableIds(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.Manifest
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.app.ActivityCompat
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.appttude.h_mal.atlas_weather.atlasWeather.ui.MainActivity
|
||||
import com.appttude.h_mal.atlas_weather.helper.ServicesHelper
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.WidgetData
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.LateInitKodein
|
||||
import org.kodein.di.generic.instance
|
||||
|
||||
/**
|
||||
* Implementation of App Widget functionality.
|
||||
*/
|
||||
private val TAG = NewAppWidget::class.java.simpleName
|
||||
class NewAppWidget : BaseWidgetClass() {
|
||||
|
||||
private val kodein = LateInitKodein()
|
||||
private val helper : ServicesHelper by kodein.instance()
|
||||
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
kodein.baseKodein = (context.applicationContext as KodeinAware).kodein
|
||||
// There may be multiple widgets active, so update all of them
|
||||
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
return
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val results = helper.fetchData()
|
||||
if (results) return@launch
|
||||
val weatherWidgetCurrent = helper.getWidgetWeather()
|
||||
|
||||
withContext(Dispatchers.Main){
|
||||
for (appWidgetId in appWidgetIds) {
|
||||
val updatePendingIntent = createUpdatePendingIntent(context, appWidgetId)
|
||||
val views = createRemoteView(context, R.layout.new_app_widget)
|
||||
bindView(context, appWidgetId, views, updatePendingIntent, weatherWidgetCurrent)
|
||||
}
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
try {
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
val thisAppWidget = ComponentName(context.packageName, NewAppWidget::class.java.name)
|
||||
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget)
|
||||
onUpdate(context, appWidgetManager, appWidgetIds)
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_listview)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "onEnabled: ", e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
// Enter relevant functionality for when the last widget is disabled
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action ==
|
||||
AppWidgetManager.ACTION_APPWIDGET_UPDATE) {
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
val thisAppWidget = ComponentName(context.packageName, NewAppWidget::class.java.name)
|
||||
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget)
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_listview)
|
||||
}
|
||||
super.onReceive(context, intent)
|
||||
}
|
||||
|
||||
private fun createForecastListIntent(
|
||||
context: Context,
|
||||
appWidgetId: Int
|
||||
): Intent {
|
||||
return Intent(context, WidgetRemoteViewsService::class.java).apply {
|
||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
||||
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindView(
|
||||
context: Context,
|
||||
appWidgetId: Int,
|
||||
views: RemoteViews,
|
||||
updatePendingIntent: PendingIntent?,
|
||||
weather: WidgetData?){
|
||||
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
|
||||
views.setInt(R.id.whole_widget_view, "setBackgroundColor", helper.getWidgetBackground())
|
||||
|
||||
weather?.let {
|
||||
|
||||
val intent = createForecastListIntent(
|
||||
context,
|
||||
appWidgetId
|
||||
)
|
||||
|
||||
views.setRemoteAdapter(R.id.widget_listview, intent)
|
||||
views.setTextViewText(R.id.widget_main_temp, it.currentTemp)
|
||||
views.setTextViewText(R.id.widget_feel_temp, "°C")
|
||||
views.setTextViewText(R.id.widget_current_location, it.location)
|
||||
views.setImageViewResource(R.id.location_icon, R.drawable.location_flag)
|
||||
// views.setImageViewBitmap(R.id.widget_current_icon, it.icon)
|
||||
|
||||
val clickPendingIntentTemplate = createClickingPendingIntent(context, MainActivity::class.java)
|
||||
views.setPendingIntentTemplate(R.id.widget_listview, clickPendingIntentTemplate)
|
||||
|
||||
views.setOnClickPendingIntent(R.id.widget_current_icon, updatePendingIntent)
|
||||
views.setOnClickPendingIntent(R.id.widget_current_location, updatePendingIntent)
|
||||
|
||||
// Instruct the widget manager to update the widget
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
|
||||
return
|
||||
}
|
||||
|
||||
Log.i(TAG, "onPostExecute: weather is empty")
|
||||
views.setTextViewText(R.id.widget_current_location, "Refresh")
|
||||
views.setImageViewResource(R.id.widget_current_icon, R.drawable.widget_error_icon)
|
||||
views.setImageViewResource(R.id.location_icon, R.drawable.refreshing)
|
||||
views.setOnClickPendingIntent(R.id.widget_current_icon, updatePendingIntent)
|
||||
views.setOnClickPendingIntent(R.id.widget_current_location, updatePendingIntent)
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViewsService
|
||||
|
||||
class WidgetRemoteViewsService : RemoteViewsService() {
|
||||
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
|
||||
return MyWidgetRemoteViewsFactory(applicationContext, intent)
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.appttude.h_mal.atlas_weather.atlasWeather.widget
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.TaskStackBuilder
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
|
||||
fun <T: Activity> createClickingPendingIntent(context: Context, activityClass: Class<T>): PendingIntent {
|
||||
val clickIntentTemplate = Intent(context, activityClass)
|
||||
|
||||
return TaskStackBuilder.create(context)
|
||||
.addNextIntentWithParentStack(clickIntentTemplate)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package com.appttude.h_mal.ui
|
||||
|
||||
import com.appttude.h_mal.R
|
||||
|
||||
val tabs = setOf(R.id.nav_home, R.id.nav_world)
|
||||
@@ -8,21 +8,17 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_home"
|
||||
android:name="com.appttude.h_mal.atlas_weather.atlasWeather.ui.home.HomeFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.ui.home.HomeFragment"
|
||||
android:label="Home"
|
||||
tools:layout="@layout/fragment_home">
|
||||
<action
|
||||
android:id="@+id/action_homeFragment_to_furtherDetailsFragment"
|
||||
app:destination="@id/furtherDetailsFragment"
|
||||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_open_enter"
|
||||
app:popExitAnim="@anim/fragment_open_exit" />
|
||||
app:destination="@id/furtherDetailsFragment" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/furtherDetailsFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.atlasWeather.ui.details.FurtherInfoFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.ui.details.FurtherInfoFragment"
|
||||
android:label="Further Details">
|
||||
<argument
|
||||
android:name="forecast"
|
||||
@@ -31,41 +27,29 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_world"
|
||||
android:name="com.appttude.h_mal.atlas_weather.atlasWeather.ui.world.WorldFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.ui.world.WorldFragment"
|
||||
android:label="World"
|
||||
tools:layout="@layout/fragment__two">
|
||||
<action
|
||||
android:id="@+id/action_worldFragment_to_addLocationFragment"
|
||||
app:destination="@id/addLocationFragment"
|
||||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_open_enter"
|
||||
app:popExitAnim="@anim/fragment_open_exit" />
|
||||
app:destination="@id/addLocationFragment"/>
|
||||
<action
|
||||
android:id="@+id/action_worldFragment_to_worldItemFragment"
|
||||
app:destination="@id/worldItemFragment"
|
||||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_open_enter"
|
||||
app:popExitAnim="@anim/fragment_open_exit" />
|
||||
app:destination="@id/worldItemFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/addLocationFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.atlasWeather.ui.world.AddLocationFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.ui.world.AddLocationFragment"
|
||||
android:label="Add Weather Location"
|
||||
tools:layout="@layout/activity_add_forecast" />
|
||||
<fragment
|
||||
android:id="@+id/worldItemFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.atlasWeather.ui.WorldItemFragment"
|
||||
android:name="com.appttude.h_mal.atlas_weather.ui.WorldItemFragment"
|
||||
android:label="Overview"
|
||||
tools:layout="@layout/fragment_home">
|
||||
<action
|
||||
android:id="@+id/action_worldItemFragment_to_furtherDetailsFragment"
|
||||
app:destination="@id/furtherDetailsFragment"
|
||||
app:enterAnim="@anim/fragment_open_enter"
|
||||
app:exitAnim="@anim/fragment_open_exit"
|
||||
app:popEnterAnim="@anim/fragment_open_enter"
|
||||
app:popExitAnim="@anim/fragment_open_exit" />
|
||||
app:destination="@id/furtherDetailsFragment" />
|
||||
<argument
|
||||
android:name="weatherDisplay"
|
||||
app:argType="com.appttude.h_mal.atlas_weather.model.forecast.WeatherDisplay" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:configure="com.appttude.h_mal.ui.widget.WidgetLocationPermissionActivity"
|
||||
android:configure="com.appttude.h_mal.atlas_weather.ui.widget.WidgetLocationPermissionActivity"
|
||||
android:initialKeyguardLayout="@layout/weather_app_widget"
|
||||
android:initialLayout="@layout/weather_app_widget"
|
||||
android:minHeight="110.0dp"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.appttude.h_mal">
|
||||
package="com.appttude.h_mal.atlas_weather">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.appttude.h_mal.application
|
||||
|
||||
import com.appttude.h_mal.data.location.LocationProviderImpl
|
||||
import com.appttude.h_mal.data.network.NetworkModule
|
||||
import com.appttude.h_mal.data.network.WeatherApi
|
||||
import com.appttude.h_mal.data.network.interceptors.NetworkConnectionInterceptor
|
||||
import com.appttude.h_mal.data.network.interceptors.QueryParamsInterceptor
|
||||
import com.appttude.h_mal.data.network.networkUtils.loggingInterceptor
|
||||
import com.appttude.h_mal.data.room.AppDatabase
|
||||
|
||||
const val LOCATION_PERMISSION_REQUEST = 505
|
||||
|
||||
class AppClass : BaseAppClass() {
|
||||
|
||||
override fun createNetworkModule(): WeatherApi {
|
||||
return NetworkModule().invoke<WeatherApi>(
|
||||
NetworkConnectionInterceptor(this),
|
||||
QueryParamsInterceptor(),
|
||||
loggingInterceptor
|
||||
) as WeatherApi
|
||||
}
|
||||
|
||||
override fun createLocationModule() = LocationProviderImpl(this)
|
||||
|
||||
override fun createRoomDatabase(): AppDatabase = AppDatabase(this)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.appttude.h_mal.atlas_weather.application
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProviderImpl
|
||||
import com.appttude.h_mal.atlas_weather.data.network.NetworkModule
|
||||
import com.appttude.h_mal.atlas_weather.data.network.WeatherApi
|
||||
import com.appttude.h_mal.atlas_weather.data.network.interceptors.NetworkConnectionInterceptor
|
||||
import com.appttude.h_mal.atlas_weather.data.network.interceptors.QueryParamsInterceptor
|
||||
import com.appttude.h_mal.atlas_weather.data.network.networkUtils.loggingInterceptor
|
||||
import com.appttude.h_mal.atlas_weather.data.room.AppDatabase
|
||||
|
||||
const val LOCATION_PERMISSION_REQUEST = 505
|
||||
|
||||
class AppClass : BaseAppClass() {
|
||||
|
||||
override fun createNetworkModule(): WeatherApi {
|
||||
return NetworkModule().invoke<WeatherApi>(
|
||||
NetworkConnectionInterceptor(this),
|
||||
QueryParamsInterceptor(),
|
||||
loggingInterceptor
|
||||
) as WeatherApi
|
||||
}
|
||||
|
||||
override fun createLocationModule() = LocationProviderImpl(this)
|
||||
|
||||
override fun createRoomDatabase(): AppDatabase = AppDatabase(this)
|
||||
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.appttude.h_mal.application
|
||||
package com.appttude.h_mal.atlas_weather.application
|
||||
|
||||
import android.app.Application
|
||||
import com.appttude.h_mal.data.location.LocationProvider
|
||||
import com.appttude.h_mal.data.network.WeatherApi
|
||||
import com.appttude.h_mal.data.prefs.PreferenceProvider
|
||||
import com.appttude.h_mal.data.repository.RepositoryImpl
|
||||
import com.appttude.h_mal.data.repository.SettingsRepositoryImpl
|
||||
import com.appttude.h_mal.data.room.AppDatabase
|
||||
import com.appttude.h_mal.helper.ServicesHelper
|
||||
import com.appttude.h_mal.viewmodel.ApplicationViewModelFactory
|
||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
||||
import com.appttude.h_mal.atlas_weather.data.network.WeatherApi
|
||||
import com.appttude.h_mal.atlas_weather.data.prefs.PreferenceProvider
|
||||
import com.appttude.h_mal.atlas_weather.data.repository.RepositoryImpl
|
||||
import com.appttude.h_mal.atlas_weather.data.repository.SettingsRepositoryImpl
|
||||
import com.appttude.h_mal.atlas_weather.data.room.AppDatabase
|
||||
import com.appttude.h_mal.atlas_weather.helper.ServicesHelper
|
||||
import com.appttude.h_mal.atlas_weather.viewmodel.ApplicationViewModelFactory
|
||||
import com.google.gson.Gson
|
||||
import org.kodein.di.Kodein
|
||||
import org.kodein.di.KodeinAware
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.appttude.h_mal.data.location
|
||||
package com.appttude.h_mal.atlas_weather.data.location
|
||||
|
||||
import android.content.Context
|
||||
import android.location.Location
|
||||
import com.appttude.h_mal.BuildConfig
|
||||
import com.appttude.h_mal.utils.createSuspend
|
||||
import com.appttude.h_mal.atlas_weather.BuildConfig
|
||||
import com.appttude.h_mal.atlas_weather.utils.createSuspend
|
||||
import com.tomtom.online.sdk.search.OnlineSearchApi
|
||||
import com.tomtom.online.sdk.search.data.common.Address
|
||||
import com.tomtom.online.sdk.search.data.reversegeocoder.ReverseGeocoderSearchQueryBuilder
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.appttude.h_mal.data.location
|
||||
package com.appttude.h_mal.atlas_weather.data.location
|
||||
|
||||
import com.appttude.h_mal.model.types.LocationType
|
||||
import com.appttude.h_mal.atlas_weather.model.types.LocationType
|
||||
|
||||
interface LocationProvider {
|
||||
suspend fun getCurrentLatLong(): Pair<Double, Double>
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.location
|
||||
package com.appttude.h_mal.atlas_weather.data.location
|
||||
|
||||
import android.Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
import android.annotation.SuppressLint
|
||||
@@ -8,7 +8,7 @@ import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.os.HandlerThread
|
||||
import androidx.annotation.RequiresPermission
|
||||
import com.appttude.h_mal.model.types.LocationType
|
||||
import com.appttude.h_mal.atlas_weather.model.types.LocationType
|
||||
import com.google.android.gms.location.FusedLocationProviderClient
|
||||
import com.google.android.gms.location.LocationCallback
|
||||
import com.google.android.gms.location.LocationRequest
|
||||
@@ -26,7 +26,7 @@ import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
class LocationProviderImpl(
|
||||
private val applicationContext: Context
|
||||
) : LocationProvider, LocationHelper(applicationContext) {
|
||||
) : com.appttude.h_mal.atlas_weather.data.location.LocationProvider, com.appttude.h_mal.atlas_weather.data.location.LocationHelper(applicationContext) {
|
||||
private var locationManager =
|
||||
applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
|
||||
private val client = FusedLocationProviderClient(applicationContext)
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.appttude.h_mal.atlas_weather.data.network
|
||||
|
||||
interface Api
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.appttude.h_mal.data.network
|
||||
package com.appttude.h_mal.atlas_weather.data.network
|
||||
|
||||
import com.appttude.h_mal.data.network.networkUtils.buildOkHttpClient
|
||||
import com.appttude.h_mal.data.network.networkUtils.createRetrofit
|
||||
import com.appttude.h_mal.atlas_weather.data.network.networkUtils.buildOkHttpClient
|
||||
import com.appttude.h_mal.atlas_weather.data.network.networkUtils.createRetrofit
|
||||
import okhttp3.Interceptor
|
||||
|
||||
open class BaseNetworkModule {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network
|
||||
package com.appttude.h_mal.atlas_weather.data.network
|
||||
|
||||
class NetworkModule : BaseNetworkModule() {
|
||||
override fun baseUrl(): String = "https://api.openweathermap.org/data/2.5/"
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network
|
||||
package com.appttude.h_mal.atlas_weather.data.network
|
||||
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.appttude.h_mal.data.network
|
||||
package com.appttude.h_mal.atlas_weather.data.network
|
||||
|
||||
import com.appttude.h_mal.data.network.response.forecast.WeatherResponse
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.WeatherResponse
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.appttude.h_mal.data.network.interceptors
|
||||
package com.appttude.h_mal.atlas_weather.data.network.interceptors
|
||||
|
||||
import android.content.Context
|
||||
import com.appttude.h_mal.utils.isInternetAvailable
|
||||
import com.appttude.h_mal.atlas_weather.utils.isInternetAvailable
|
||||
import okhttp3.Interceptor
|
||||
import java.io.IOException
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.appttude.h_mal.atlas_weather.data.network.interceptors
|
||||
|
||||
import okhttp3.Interceptor
|
||||
|
||||
interface NetworkInterceptor : Interceptor
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.appttude.h_mal.data.network.interceptors
|
||||
package com.appttude.h_mal.atlas_weather.data.network.interceptors
|
||||
|
||||
import com.appttude.h_mal.BuildConfig
|
||||
import com.appttude.h_mal.atlas_weather.BuildConfig
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.appttude.h_mal.data.network.networkUtils
|
||||
package com.appttude.h_mal.atlas_weather.data.network.networkUtils
|
||||
|
||||
import com.appttude.h_mal.data.network.interceptors.NetworkConnectionInterceptor
|
||||
import com.appttude.h_mal.data.network.interceptors.NetworkInterceptor
|
||||
import com.appttude.h_mal.atlas_weather.data.network.interceptors.NetworkInterceptor
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network.response.forecast
|
||||
package com.appttude.h_mal.atlas_weather.data.network.response.forecast
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network.response.forecast
|
||||
package com.appttude.h_mal.atlas_weather.data.network.response.forecast
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network.response.forecast
|
||||
package com.appttude.h_mal.atlas_weather.data.network.response.forecast
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network.response.forecast
|
||||
package com.appttude.h_mal.atlas_weather.data.network.response.forecast
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network.response.forecast
|
||||
package com.appttude.h_mal.atlas_weather.data.network.response.forecast
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network.response.forecast
|
||||
package com.appttude.h_mal.atlas_weather.data.network.response.forecast
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network.response.forecast
|
||||
package com.appttude.h_mal.atlas_weather.data.network.response.forecast
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.network.response.forecast
|
||||
package com.appttude.h_mal.atlas_weather.data.network.response.forecast
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.appttude.h_mal.data.prefs
|
||||
package com.appttude.h_mal.atlas_weather.data.prefs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.appttude.h_mal.data.room.entity.CURRENT_LOCATION
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.CURRENT_LOCATION
|
||||
|
||||
/**
|
||||
* Shared preferences to save & load last timestamp
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.appttude.h_mal.data.repository
|
||||
package com.appttude.h_mal.atlas_weather.data.repository
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.appttude.h_mal.data.network.response.forecast.WeatherResponse
|
||||
import com.appttude.h_mal.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.WeatherResponse
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||
|
||||
interface Repository {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.appttude.h_mal.data.repository
|
||||
package com.appttude.h_mal.atlas_weather.data.repository
|
||||
|
||||
import com.appttude.h_mal.data.network.ResponseUnwrap
|
||||
import com.appttude.h_mal.data.network.WeatherApi
|
||||
import com.appttude.h_mal.data.network.response.forecast.WeatherResponse
|
||||
import com.appttude.h_mal.data.prefs.LOCATION_CONST
|
||||
import com.appttude.h_mal.data.prefs.PreferenceProvider
|
||||
import com.appttude.h_mal.data.room.AppDatabase
|
||||
import com.appttude.h_mal.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.utils.FALLBACK_TIME
|
||||
import com.appttude.h_mal.atlas_weather.data.network.ResponseUnwrap
|
||||
import com.appttude.h_mal.atlas_weather.data.network.WeatherApi
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.WeatherResponse
|
||||
import com.appttude.h_mal.atlas_weather.data.prefs.LOCATION_CONST
|
||||
import com.appttude.h_mal.atlas_weather.data.prefs.PreferenceProvider
|
||||
import com.appttude.h_mal.atlas_weather.data.room.AppDatabase
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.atlas_weather.utils.FALLBACK_TIME
|
||||
|
||||
|
||||
class RepositoryImpl(
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.data.repository
|
||||
package com.appttude.h_mal.atlas_weather.data.repository
|
||||
|
||||
interface SettingsRepository {
|
||||
fun isNotificationsEnabled(): Boolean
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.appttude.h_mal.data.repository
|
||||
package com.appttude.h_mal.atlas_weather.data.repository
|
||||
|
||||
import com.appttude.h_mal.data.prefs.PreferenceProvider
|
||||
import com.appttude.h_mal.atlas_weather.data.prefs.PreferenceProvider
|
||||
|
||||
class SettingsRepositoryImpl(
|
||||
private val prefs: PreferenceProvider
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.appttude.h_mal.data.room
|
||||
package com.appttude.h_mal.atlas_weather.data.room
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import com.appttude.h_mal.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||
|
||||
@Database(
|
||||
entities = [EntityItem::class],
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.appttude.h_mal.data.room
|
||||
package com.appttude.h_mal.atlas_weather.data.room
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.ProvidedTypeConverter
|
||||
import androidx.room.TypeConverter
|
||||
import com.appttude.h_mal.model.weather.FullWeather
|
||||
import com.appttude.h_mal.atlas_weather.model.weather.FullWeather
|
||||
import com.google.gson.Gson
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.android.kodein
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.appttude.h_mal.data.room
|
||||
package com.appttude.h_mal.atlas_weather.data.room
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.appttude.h_mal.data.room.entity.CURRENT_LOCATION
|
||||
import com.appttude.h_mal.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.CURRENT_LOCATION
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||
|
||||
@Dao
|
||||
interface WeatherDao {
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.appttude.h_mal.data.room.entity
|
||||
package com.appttude.h_mal.atlas_weather.data.room.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.appttude.h_mal.model.weather.FullWeather
|
||||
import com.appttude.h_mal.atlas_weather.model.weather.FullWeather
|
||||
|
||||
|
||||
const val CURRENT_LOCATION = "CurrentLocation"
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.helper
|
||||
package com.appttude.h_mal.atlas_weather.helper
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
@@ -1,21 +1,21 @@
|
||||
package com.appttude.h_mal.helper
|
||||
package com.appttude.h_mal.atlas_weather.helper
|
||||
|
||||
import android.Manifest
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.annotation.RequiresPermission
|
||||
import com.appttude.h_mal.data.location.LocationProvider
|
||||
import com.appttude.h_mal.data.repository.Repository
|
||||
import com.appttude.h_mal.data.repository.SettingsRepository
|
||||
import com.appttude.h_mal.data.room.entity.CURRENT_LOCATION
|
||||
import com.appttude.h_mal.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.model.weather.FullWeather
|
||||
import com.appttude.h_mal.model.widget.InnerWidgetCellData
|
||||
import com.appttude.h_mal.model.widget.InnerWidgetData
|
||||
import com.appttude.h_mal.model.widget.WidgetData
|
||||
import com.appttude.h_mal.model.widget.WidgetWeatherCollection
|
||||
import com.appttude.h_mal.utils.toSmallDayName
|
||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
||||
import com.appttude.h_mal.atlas_weather.data.repository.Repository
|
||||
import com.appttude.h_mal.atlas_weather.data.repository.SettingsRepository
|
||||
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.model.weather.FullWeather
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.InnerWidgetCellData
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.InnerWidgetData
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.WidgetData
|
||||
import com.appttude.h_mal.atlas_weather.model.widget.WidgetWeatherCollection
|
||||
import com.appttude.h_mal.atlas_weather.utils.toSmallDayName
|
||||
import com.squareup.picasso.Picasso
|
||||
import com.squareup.picasso.Target
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.appttude.h_mal.atlas_weather.model.forecast
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.appttude.h_mal.atlas_weather.model.weather.DailyWeather
|
||||
import com.appttude.h_mal.atlas_weather.utils.toDayName
|
||||
import com.appttude.h_mal.atlas_weather.utils.toDayString
|
||||
import com.appttude.h_mal.atlas_weather.utils.toTime
|
||||
|
||||
|
||||
data class Forecast(
|
||||
val date: String?,
|
||||
val day: String?,
|
||||
val condition: String?,
|
||||
val weatherIcon: String?,
|
||||
val mainTemp: String?,
|
||||
val minorTemp: String?,
|
||||
val averageTemp: String?,
|
||||
val windText: String?,
|
||||
val precipitation: String?,
|
||||
val humidity: String?,
|
||||
val uvi: String?,
|
||||
val sunrise: String?,
|
||||
val sunset: String?,
|
||||
val cloud: String?
|
||||
): Parcelable{
|
||||
|
||||
constructor(parcel: Parcel) : this(
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString()
|
||||
) {
|
||||
}
|
||||
|
||||
constructor(dailyWeather: DailyWeather) : this(
|
||||
dailyWeather.dt?.toDayString(),
|
||||
dailyWeather.dt?.toDayName(),
|
||||
dailyWeather.description,
|
||||
dailyWeather.icon,
|
||||
dailyWeather.max?.toInt().toString(),
|
||||
dailyWeather.min?.toInt().toString(),
|
||||
dailyWeather.average?.toInt().toString(),
|
||||
dailyWeather.windSpeed?.toInt().toString(),
|
||||
(dailyWeather.pop?.times(100))?.toInt().toString(),
|
||||
dailyWeather.humidity?.toString(),
|
||||
dailyWeather.uvi?.toInt().toString(),
|
||||
dailyWeather.sunrise?.toTime(),
|
||||
dailyWeather.sunset?.toTime(),
|
||||
dailyWeather.clouds?.toString()
|
||||
)
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
parcel.writeString(date)
|
||||
parcel.writeString(day)
|
||||
parcel.writeString(condition)
|
||||
parcel.writeString(weatherIcon)
|
||||
parcel.writeString(mainTemp)
|
||||
parcel.writeString(minorTemp)
|
||||
parcel.writeString(averageTemp)
|
||||
parcel.writeString(windText)
|
||||
parcel.writeString(precipitation)
|
||||
parcel.writeString(humidity)
|
||||
parcel.writeString(uvi)
|
||||
parcel.writeString(sunrise)
|
||||
parcel.writeString(sunset)
|
||||
parcel.writeString(cloud)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<Forecast> {
|
||||
override fun createFromParcel(parcel: Parcel): Forecast {
|
||||
return Forecast(parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<Forecast?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.appttude.h_mal.atlas_weather.model.forecast
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.atlas_weather.model.weather.Hour
|
||||
|
||||
|
||||
data class WeatherDisplay(
|
||||
val averageTemp: Double?,
|
||||
var unit: String?,
|
||||
var location: String?,
|
||||
val iconURL: String?,
|
||||
val description: String?,
|
||||
val hourly: List<Hour>?,
|
||||
val forecast: List<Forecast>?,
|
||||
val windSpeed: String?,
|
||||
val windDirection: String?,
|
||||
val precipitation: String?,
|
||||
val humidity: String?,
|
||||
val clouds: String?,
|
||||
val lat: Double = 0.00,
|
||||
val lon: Double = 0.00,
|
||||
var displayName: String?
|
||||
): Parcelable {
|
||||
|
||||
constructor(parcel: Parcel) : this(
|
||||
parcel.readValue(Double::class.java.classLoader) as? Double,
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.createTypedArrayList(Hour),
|
||||
parcel.createTypedArrayList(Forecast),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readString(),
|
||||
parcel.readDouble(),
|
||||
parcel.readDouble(),
|
||||
parcel.readString()
|
||||
) {
|
||||
}
|
||||
|
||||
constructor(entity: EntityItem) : this(
|
||||
entity.weather.current?.temp,
|
||||
entity.weather.temperatureUnit,
|
||||
entity.id,
|
||||
entity.weather.current?.icon,
|
||||
entity.weather.current?.description,
|
||||
entity.weather.hourly,
|
||||
entity.weather.daily?.drop(1)?.map { Forecast(it) },
|
||||
entity.weather.current?.windSpeed?.toString(),
|
||||
entity.weather.current?.windDeg?.toString(),
|
||||
entity.weather.daily?.get(0)?.pop?.times(100)?.toInt()?.toString(),
|
||||
entity.weather.current?.humidity?.toString(),
|
||||
entity.weather.current?.clouds?.toString(),
|
||||
entity.weather.lat,
|
||||
entity.weather.lon,
|
||||
entity.weather.locationString
|
||||
)
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
parcel.writeValue(averageTemp)
|
||||
parcel.writeString(unit)
|
||||
parcel.writeString(location)
|
||||
parcel.writeString(iconURL)
|
||||
parcel.writeString(description)
|
||||
parcel.writeTypedList(hourly)
|
||||
parcel.writeTypedList(forecast)
|
||||
parcel.writeString(windSpeed)
|
||||
parcel.writeString(windDirection)
|
||||
parcel.writeString(precipitation)
|
||||
parcel.writeString(humidity)
|
||||
parcel.writeString(clouds)
|
||||
parcel.writeDouble(lat)
|
||||
parcel.writeDouble(lon)
|
||||
parcel.writeString(displayName)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<WeatherDisplay> {
|
||||
override fun createFromParcel(parcel: Parcel): WeatherDisplay {
|
||||
return WeatherDisplay(parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<WeatherDisplay?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.appttude.h_mal.atlas_weather.model.types
|
||||
|
||||
enum class LocationType{
|
||||
City,
|
||||
Town
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.appttude.h_mal.model.weather
|
||||
package com.appttude.h_mal.atlas_weather.model.weather
|
||||
|
||||
import com.appttude.h_mal.data.network.response.forecast.Current
|
||||
import com.appttude.h_mal.utils.generateIconUrlString
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.Current
|
||||
import com.appttude.h_mal.atlas_weather.utils.generateIconUrlString
|
||||
|
||||
data class Current(
|
||||
val dt: Int? = null,
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.appttude.h_mal.model.weather
|
||||
package com.appttude.h_mal.atlas_weather.model.weather
|
||||
|
||||
import com.appttude.h_mal.data.network.response.forecast.DailyItem
|
||||
import com.appttude.h_mal.utils.generateIconUrlString
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.DailyItem
|
||||
import com.appttude.h_mal.atlas_weather.utils.generateIconUrlString
|
||||
|
||||
|
||||
data class DailyWeather(
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.appttude.h_mal.model.weather
|
||||
package com.appttude.h_mal.atlas_weather.model.weather
|
||||
|
||||
import com.appttude.h_mal.data.network.response.forecast.WeatherResponse
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.WeatherResponse
|
||||
|
||||
data class FullWeather(
|
||||
val current: Current? = null,
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.appttude.h_mal.atlas_weather.model.weather
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.appttude.h_mal.atlas_weather.utils.generateIconUrlString
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.Hour as ForecastHour
|
||||
|
||||
|
||||
data class Hour(
|
||||
val dt: Int? = null,
|
||||
val temp: Double? = null,
|
||||
val icon: String? = null
|
||||
): Parcelable {
|
||||
|
||||
constructor(parcel: Parcel) : this(
|
||||
parcel.readValue(Int::class.java.classLoader) as? Int,
|
||||
parcel.readValue(Double::class.java.classLoader) as? Double,
|
||||
parcel.readString()
|
||||
) {
|
||||
}
|
||||
|
||||
constructor(hour: ForecastHour) : this(
|
||||
hour.dt,
|
||||
hour.temp,
|
||||
generateIconUrlString(hour.weather?.getOrNull(0)?.icon)
|
||||
)
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
parcel.writeValue(dt)
|
||||
parcel.writeValue(temp)
|
||||
parcel.writeString(icon)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<Hour> {
|
||||
override fun createFromParcel(parcel: Parcel): Hour {
|
||||
return Hour(parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<Hour?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.model.widget
|
||||
package com.appttude.h_mal.atlas_weather.model.widget
|
||||
|
||||
import android.graphics.Bitmap
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.ui
|
||||
package com.appttude.h_mal.atlas_weather.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
@@ -10,8 +10,7 @@ import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.appttude.h_mal.R
|
||||
import com.appttude.h_mal.monoWeather.ui.settings.UnitSettingsActivity
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import kotlinx.android.synthetic.main.activity_main_navigation.*
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.appttude.h_mal.atlas_weather.utils
|
||||
|
||||
val FALLBACK_TIME: Long = 300000L
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.utils
|
||||
package com.appttude.h_mal.atlas_weather.utils
|
||||
|
||||
/**
|
||||
* Used with livedata<T> to make observation lifecycle aware
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.utils
|
||||
package com.appttude.h_mal.atlas_weather.utils
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.utils
|
||||
package com.appttude.h_mal.atlas_weather.utils
|
||||
|
||||
fun printToLog(msg: String) {
|
||||
println("widget monitoring: $msg")
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.appttude.h_mal.utils
|
||||
package com.appttude.h_mal.atlas_weather.utils
|
||||
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.NavDirections
|
||||
import androidx.navigation.Navigation
|
||||
import com.appttude.h_mal.R
|
||||
import com.appttude.h_mal.atlas_weather.R
|
||||
|
||||
fun Fragment.navigateToFragment(newFragment: Fragment){
|
||||
childFragmentManager.beginTransaction()
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.appttude.h_mal.utils
|
||||
package com.appttude.h_mal.atlas_weather.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user