mirror of
https://github.com/hmalik144/Weather-apps.git
synced 2026-03-18 07:26:04 +00:00
- Fixed android S issues
- Dialog box completed - Widget creation activity UI test added Took 1 hour 53 minutes
This commit is contained in:
@@ -8,7 +8,7 @@ import com.appttude.h_mal.atlas_weather.utils.Stubs
|
|||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
|
|
||||||
open class BaseTest() {
|
open class BaseTest {
|
||||||
|
|
||||||
lateinit var testApp: TestAppClass
|
lateinit var testApp: TestAppClass
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather.monoWeather.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>(WidgetLocationPermissionActivity::class.java, false, false)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun demo_test() {
|
||||||
|
val i = Intent()
|
||||||
|
i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 112)
|
||||||
|
mActivityTestRule.launchActivity(i)
|
||||||
|
|
||||||
|
Espresso.onView((ViewMatchers.withId(R.id.declaration_text))).check(matches(isDisplayed()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ abstract class BaseWidgetClass : AppWidgetProvider(){
|
|||||||
intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||||
val idArray = intArrayOf(appWidgetId)
|
val idArray = intArrayOf(appWidgetId)
|
||||||
intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray)
|
intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray)
|
||||||
|
|
||||||
return PendingIntent.getBroadcast(
|
return PendingIntent.getBroadcast(
|
||||||
context, seconds, intentUpdate,
|
context, seconds, intentUpdate,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -13,6 +14,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/forecast_listview"
|
android:id="@+id/forecast_listview"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
tools:listitem="@layout/db_list_item">
|
tools:listitem="@layout/db_list_item">
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.MainActivity"
|
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.MainActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:theme="@style/AppTheme.NoActionBar">
|
android:theme="@style/AppTheme.NoActionBar"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
@@ -30,13 +31,15 @@
|
|||||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.settings.UnitSettingsActivity"
|
android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.settings.UnitSettingsActivity"
|
||||||
android:label="Settings" />
|
android:label="Settings" />
|
||||||
|
|
||||||
<activity android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.widget.WidgetLocationPermissionActivity">
|
<activity android:name="com.appttude.h_mal.atlas_weather.monoWeather.ui.widget.WidgetLocationPermissionActivity"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<receiver android:name="com.appttude.h_mal.atlas_weather.monoWeather.widget.NewAppWidget">
|
<receiver android:name="com.appttude.h_mal.atlas_weather.monoWeather.widget.NewAppWidget"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
|
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
|
||||||
@@ -48,9 +51,6 @@
|
|||||||
android:resource="@xml/new_app_widget_info" />
|
android:resource="@xml/new_app_widget_info" />
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<service
|
|
||||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.widget.WidgetRemoteViewsService"
|
|
||||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
|
||||||
<service
|
<service
|
||||||
android:name="com.appttude.h_mal.atlas_weather.monoWeather.widget.WidgetJobServiceIntent"
|
android:name="com.appttude.h_mal.atlas_weather.monoWeather.widget.WidgetJobServiceIntent"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.monoWeather.dialog
|
package com.appttude.h_mal.atlas_weather.monoWeather.dialog
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.Resources
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
interface DeclarationBuilder{
|
interface DeclarationBuilder{
|
||||||
val link: String
|
val link: String
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ abstract class BaseDeclarationDialog(val context: Context): DeclarationBuilder {
|
|||||||
abstract override val link: String
|
abstract override val link: String
|
||||||
abstract override val message: String
|
abstract override val message: String
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.N)
|
|
||||||
fun showDialog(agreeCallback: () -> Unit = { Unit }, disagreeCallback: () -> Unit = { Unit }) {
|
fun showDialog(agreeCallback: () -> Unit = { Unit }, disagreeCallback: () -> Unit = { Unit }) {
|
||||||
val myMessage = buildMessage()
|
val myMessage = buildMessage()
|
||||||
|
|
||||||
@@ -38,8 +37,8 @@ abstract class BaseDeclarationDialog(val context: Context): DeclarationBuilder {
|
|||||||
alertDialog.show()
|
alertDialog.show()
|
||||||
|
|
||||||
// Make the textview clickable. Must be called after show()
|
// Make the textview clickable. Must be called after show()
|
||||||
val msgTxt = alertDialog.findViewById<View>(R.id.message) as TextView?
|
val msgTxt = alertDialog.findViewById<View>(android.R.id.message) as TextView?
|
||||||
msgTxt!!.movementMethod = LinkMovementMethod.getInstance()
|
msgTxt?.movementMethod = LinkMovementMethod.getInstance()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.kodein.di.android.x.kodein
|
|||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
abstract class BaseFragment() : Fragment(), KodeinAware {
|
abstract class BaseFragment : Fragment(), KodeinAware {
|
||||||
|
|
||||||
override val kodein by kodein()
|
override val kodein by kodein()
|
||||||
val factory by instance<ApplicationViewModelFactory>()
|
val factory by instance<ApplicationViewModelFactory>()
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.observe
|
import androidx.lifecycle.observe
|
||||||
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.monoWeather.dialog.PermissionsDeclarationDialog
|
import com.appttude.h_mal.atlas_weather.monoWeather.dialog.PermissionsDeclarationDialog
|
||||||
@@ -34,7 +33,6 @@ class HomeFragment : BaseFragment() {
|
|||||||
return inflater.inflate(R.layout.fragment_home, container, false)
|
return inflater.inflate(R.layout.fragment_home, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
@@ -45,18 +43,13 @@ class HomeFragment : BaseFragment() {
|
|||||||
navigateTo(directions)
|
navigateTo(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
forecast_listview.apply {
|
forecast_listview.adapter = recyclerAdapter
|
||||||
layoutManager = LinearLayoutManager(context)
|
|
||||||
adapter = recyclerAdapter
|
|
||||||
}
|
|
||||||
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
|
||||||
PermissionsDeclarationDialog(requireContext()).showDialog(agreeCallback = {
|
PermissionsDeclarationDialog(requireContext()).showDialog(agreeCallback = {
|
||||||
getPermissionResult(Manifest.permission.ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
getPermissionResult(Manifest.permission.ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
||||||
viewModel.fetchData()
|
viewModel.fetchData()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
swipe_refresh.apply {
|
swipe_refresh.apply {
|
||||||
setOnRefreshListener {
|
setOnRefreshListener {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import android.appwidget.AppWidgetManager.*
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.method.LinkMovementMethod
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat.checkSelfPermission
|
import androidx.core.app.ActivityCompat.checkSelfPermission
|
||||||
@@ -17,11 +18,16 @@ import kotlinx.android.synthetic.monoWeather.permissions_declaration_dialog.*
|
|||||||
const val PERMISSION_CODE = 401
|
const val PERMISSION_CODE = 401
|
||||||
|
|
||||||
class WidgetLocationPermissionActivity : AppCompatActivity(), DeclarationBuilder {
|
class WidgetLocationPermissionActivity : AppCompatActivity(), DeclarationBuilder {
|
||||||
|
override val link: String = "https://sites.google.com/view/hmaldev/home/monochrome"
|
||||||
|
override var message: String = ""
|
||||||
|
|
||||||
private var mAppWidgetId = INVALID_APPWIDGET_ID
|
private var mAppWidgetId = INVALID_APPWIDGET_ID
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
message = readFromResources(R.string.widget_declaration)
|
||||||
|
|
||||||
// Set the result to CANCELED. This will cause the widget host to cancel
|
// Set the result to CANCELED. This will cause the widget host to cancel
|
||||||
// out of the widget placement if the user presses the back button.
|
// out of the widget placement if the user presses the back button.
|
||||||
setResult(RESULT_CANCELED)
|
setResult(RESULT_CANCELED)
|
||||||
@@ -38,7 +44,10 @@ class WidgetLocationPermissionActivity : AppCompatActivity(), DeclarationBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
setContentView(R.layout.permissions_declaration_dialog)
|
setContentView(R.layout.permissions_declaration_dialog)
|
||||||
findViewById<TextView>(R.id.declaration_text).setText(buildMessage())
|
findViewById<TextView>(R.id.declaration_text).apply {
|
||||||
|
text = buildMessage()
|
||||||
|
movementMethod = LinkMovementMethod.getInstance()
|
||||||
|
}
|
||||||
|
|
||||||
submit.setOnClickListener {
|
submit.setOnClickListener {
|
||||||
if (checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PERMISSION_GRANTED) {
|
if (checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PERMISSION_GRANTED) {
|
||||||
@@ -88,7 +97,4 @@ class WidgetLocationPermissionActivity : AppCompatActivity(), DeclarationBuilder
|
|||||||
sendBroadcast(this)
|
sendBroadcast(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val link: String = "https://sites.google.com/view/hmaldev/home/monochrome"
|
|
||||||
override val message: String = readFromResources(R.string.widget_declaration)
|
|
||||||
}
|
}
|
||||||
@@ -2,24 +2,21 @@ package com.appttude.h_mal.atlas_weather.monoWeather.widget
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
|
import android.app.PendingIntent.FLAG_IMMUTABLE
|
||||||
import android.app.TaskStackBuilder
|
import android.app.TaskStackBuilder
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.appwidget.AppWidgetProvider
|
import android.appwidget.AppWidgetProvider
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import androidx.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.core.app.JobIntentService
|
import androidx.core.app.JobIntentService
|
||||||
import com.appttude.h_mal.atlas_weather.helper.ServicesHelper
|
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.kodein.di.KodeinAware
|
|
||||||
import org.kodein.di.LateInitKodein
|
|
||||||
import org.kodein.di.generic.instance
|
|
||||||
|
|
||||||
abstract class BaseWidgetServiceIntentClass<T : AppWidgetProvider> : JobIntentService() {
|
abstract class BaseWidgetServiceIntentClass<T : AppWidgetProvider> : JobIntentService() {
|
||||||
|
|
||||||
@@ -45,9 +42,12 @@ abstract class BaseWidgetServiceIntentClass<T: AppWidgetProvider> : JobIntentSer
|
|||||||
intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||||
val idArray = intArrayOf(appWidgetId)
|
val idArray = intArrayOf(appWidgetId)
|
||||||
intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray)
|
intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray)
|
||||||
return PendingIntent.getBroadcast(
|
|
||||||
this, seconds, intentUpdate,
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
PendingIntent.getBroadcast(this, seconds, intentUpdate, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
} else {
|
||||||
|
PendingIntent.getBroadcast(this, seconds, intentUpdate, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,7 +59,7 @@ abstract class BaseWidgetServiceIntentClass<T: AppWidgetProvider> : JobIntentSer
|
|||||||
|
|
||||||
return TaskStackBuilder.create(this)
|
return TaskStackBuilder.create(this)
|
||||||
.addNextIntentWithParentStack(clickIntentTemplate)
|
.addNextIntentWithParentStack(clickIntentTemplate)
|
||||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
|
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setImageView(
|
fun setImageView(
|
||||||
|
|||||||
Reference in New Issue
Block a user