WSDOT / wsdot-kotlin-app

Source Code for the WSDOT Android Application
GNU General Public License v3.0
1 stars 3 forks source link

Emergency Alert Messaging #149

Closed englehorn closed 2 years ago

englehorn commented 2 years ago

Emergency Alert Messaging

The WSDOT mobile app is set up to provide time-sensitive alert messages via a server-side data file EventStatus.js

https://data.wsdot.wa.gov/mobile/EventStatus.js

This file can also be modified to deliver important emergency information in the case of natural disasters and extreme weather.

Example:

{
"startDate": "2022-06-17",
"endDate": "2022-06-17",
"themeId": 1,
"bannerText": "This is a Test Emergency Alert",
"title": "Emergency Alert",
"details": "This is a test"
}
englehorn commented 2 years ago

"themeId" can be used to assign custom styling for emergency alerts.

Theme 0 Theme 0

englehorn commented 2 years ago

Theme 1

Theme 1

englehorn commented 2 years ago

Add additional themes to match the event themes found in iOS version file ThemeManager.swift

englehorn commented 2 years ago

There are some issues with the way new themes are loading in the Android app. The MainActivity.kt getTheme() method is called before the views are instantiated in the onCreate() method. This results in the AndroidManifest.xml default theme and styles being loaded the first time a new EventStatus.js file is detected.

One solution is to check the app themeId and event status shared preferences themeId for a match when a new event is detected. If there is a match then display the correct themed alert banner. This will work, however, it requires an additional loading of the application.

MainActivity.kt

Example Code:

 // handle event banner
        eventViewModel = ViewModelProvider(this, viewModelFactory).get(EventBannerViewModel::class.java)
        eventViewModel.eventStatus.observe(this, Observer { eventResponse ->
            eventResponse.data?.let {

                val settings = PreferenceManager.getDefaultSharedPreferences(this)
                val themeId = settings.getInt(getString(R.string.pref_key_theme), 0)
                val editor = settings.edit()

                editor.putInt(getString(R.string.pref_key_theme), it.themeId)
                editor.putString(getString(R.string.pref_key_current_event), it.title)
                editor.commit()

                if (TimeUtils.currentDateInRange(it.startDate, it.endDate, "yyyy-MM-dd")) {

                    eventTitle = it.title

                    if (it.themeId == themeId) {
                        navView.menu.setGroupVisible(R.id.event_banner_group, true)
                        navView.menu.findItem(R.id.event_banner).actionView.findViewById<TextView>(R.id.event_banner_text).text =
                            it.bannerText

                    }

                } else {
                    navView.menu.setGroupVisible(R.id.event_banner_group, false)

                    editor.putString(getString(R.string.pref_key_last_seen_event), "")
                    editor.putString(getString(R.string.pref_key_current_event), "")
                    editor.putInt(getString(R.string.pref_key_theme), 0)
                    editor.apply()
                }
            }
        })

        notificationsViewModel = ViewModelProvider(this, viewModelFactory).get(
            NotificationsViewModel::class.java
        )

        notificationsViewModel.topics.observe(this, Observer { topics ->
            topics.data?.let {
                for (topic in it) {
                    notificationsViewModel.updateSubscription(
                        topic.topic,
                        topic.subscribed
                    )
                }
            }
        })