Compare commits
9 Commits
v2.3.3-pat
...
v2.3.3-pat
Author | SHA1 | Date | |
---|---|---|---|
77864cbef4 | |||
32c580bac7 | |||
85fa0cae11 | |||
05f2a745c2 | |||
ef2e89b6ff | |||
a306d92282 | |||
da9fc362af | |||
ff83cfd953 | |||
5d9dcd9701 |
@ -7,8 +7,6 @@ apply plugin: 'com.google.firebase.crashlytics'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
apply plugin: 'realm-android'
|
||||
|
||||
def apikeyPropertiesFile = rootProject.file("apikey.properties")
|
||||
def apikeyProperties = new Properties()
|
||||
apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
|
||||
@ -88,6 +86,10 @@ dependencies {
|
||||
// EventBus
|
||||
implementation 'org.greenrobot:eventbus:3.2.0'
|
||||
|
||||
// Room
|
||||
implementation "androidx.room:room-runtime:2.3.0"
|
||||
kapt "androidx.room:room-compiler:2.3.0"
|
||||
|
||||
// Navigation
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
|
||||
|
@ -7,10 +7,6 @@ import androidx.appcompat.app.AppCompatDelegate
|
||||
import com.chibatching.kotpref.Kotpref
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import net.danlew.android.joda.JodaTimeAndroid
|
||||
|
||||
class AWApplication : Application() {
|
||||
override fun onCreate() {
|
||||
@ -24,12 +20,5 @@ class AWApplication : Application() {
|
||||
|
||||
// Dark theme
|
||||
AppCompatDelegate.setDefaultNightMode(Preferences.darkThemePreference)
|
||||
|
||||
// Realm
|
||||
Realm.init(this)
|
||||
val config = RealmConfiguration.Builder()
|
||||
.deleteRealmIfMigrationNeeded()
|
||||
.build()
|
||||
Realm.setDefaultConfiguration(config)
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ class FixedFocusScrollView @JvmOverloads constructor(
|
||||
var isScrollable = true
|
||||
|
||||
override fun scrollTo(x: Int, y: Int) {
|
||||
if (isScrollable) {
|
||||
if (isScrollable || !isLaidOut) {
|
||||
super.scrollTo(x, y)
|
||||
}
|
||||
}
|
||||
|
@ -3,32 +3,37 @@ package com.tommasoberlose.anotherwidget.db
|
||||
import android.content.Context
|
||||
import android.provider.CalendarContract
|
||||
import android.util.Log
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Database
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import com.chibatching.kotpref.bulk
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.applyFilters
|
||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.sortEvents
|
||||
import com.tommasoberlose.anotherwidget.models.Event
|
||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmResults
|
||||
import java.util.*
|
||||
import kotlin.Comparator
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class EventRepository(val context: Context) {
|
||||
private val realm by lazy { Realm.getDefaultInstance() }
|
||||
private val db by lazy { EventDatabase.getDatabase(context) }
|
||||
|
||||
fun saveEvents(eventList: List<Event>) {
|
||||
realm.executeTransaction { realm ->
|
||||
realm.where(Event::class.java).findAll().deleteAllFromRealm()
|
||||
realm.copyToRealm(eventList)
|
||||
db.runInTransaction{
|
||||
db.dao().run {
|
||||
deleteAll()
|
||||
insertAll(eventList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clearEvents() {
|
||||
realm.executeTransaction { realm ->
|
||||
realm.where(Event::class.java).findAll().deleteAllFromRealm()
|
||||
}
|
||||
db.dao().deleteAll()
|
||||
}
|
||||
|
||||
fun resetNextEventData() {
|
||||
@ -44,11 +49,11 @@ class EventRepository(val context: Context) {
|
||||
}
|
||||
|
||||
fun saveNextEventData(event: Event) {
|
||||
Preferences.nextEventId = event.eventID
|
||||
Preferences.nextEventId = event.id
|
||||
}
|
||||
|
||||
fun getNextEvent(): Event? {
|
||||
val nextEvent = getEventByEventId(Preferences.nextEventId)
|
||||
val nextEvent = getEventById(Preferences.nextEventId)
|
||||
val now = Calendar.getInstance().timeInMillis
|
||||
val limit = Calendar.getInstance().apply {
|
||||
timeInMillis = now
|
||||
@ -64,43 +69,33 @@ class EventRepository(val context: Context) {
|
||||
else -> add(Calendar.HOUR, 6)
|
||||
}
|
||||
}
|
||||
val event = if (nextEvent != null && nextEvent.endDate > now && nextEvent.startDate <= limit.timeInMillis) {
|
||||
return if (nextEvent != null && nextEvent.endDate > now && nextEvent.startDate <= limit.timeInMillis) {
|
||||
nextEvent
|
||||
} else {
|
||||
val events = getEvents()
|
||||
if (events.isNotEmpty()) {
|
||||
val newNextEvent = events.first()
|
||||
Preferences.nextEventId = newNextEvent.eventID
|
||||
Preferences.nextEventId = newNextEvent.id
|
||||
newNextEvent
|
||||
} else {
|
||||
resetNextEventData()
|
||||
null
|
||||
}
|
||||
}
|
||||
return try {
|
||||
realm.copyFromRealm(event!!)
|
||||
} catch (ex: Exception) {
|
||||
event
|
||||
}
|
||||
}
|
||||
|
||||
fun getEventByEventId(id: Long): Event? {
|
||||
val event = realm.where(Event::class.java).equalTo("eventID", id).findFirst()
|
||||
return try {
|
||||
realm.copyFromRealm(event!!)
|
||||
} catch (ex: Exception) {
|
||||
event
|
||||
}
|
||||
fun getEventById(id: Long): Event? {
|
||||
return db.dao().findById(id)
|
||||
}
|
||||
|
||||
fun goToNextEvent() {
|
||||
val eventList = getEvents()
|
||||
if (eventList.isNotEmpty()) {
|
||||
val index = eventList.indexOfFirst { it.eventID == Preferences.nextEventId }
|
||||
val index = eventList.indexOfFirst { it.id == Preferences.nextEventId }
|
||||
if (index > -1 && index < eventList.size - 1) {
|
||||
Preferences.nextEventId = eventList[index + 1].eventID
|
||||
Preferences.nextEventId = eventList[index + 1].id
|
||||
} else {
|
||||
Preferences.nextEventId = eventList.first().eventID
|
||||
Preferences.nextEventId = eventList.first().id
|
||||
}
|
||||
} else {
|
||||
resetNextEventData()
|
||||
@ -114,11 +109,11 @@ class EventRepository(val context: Context) {
|
||||
fun goToPreviousEvent() {
|
||||
val eventList = getEvents()
|
||||
if (eventList.isNotEmpty()) {
|
||||
val index = eventList.indexOfFirst { it.eventID == Preferences.nextEventId }
|
||||
val index = eventList.indexOfFirst { it.id == Preferences.nextEventId }
|
||||
if (index > 0) {
|
||||
Preferences.nextEventId = eventList[index - 1].eventID
|
||||
Preferences.nextEventId = eventList[index - 1].id
|
||||
} else {
|
||||
Preferences.nextEventId = eventList.last().eventID
|
||||
Preferences.nextEventId = eventList.last().id
|
||||
}
|
||||
} else {
|
||||
resetNextEventData()
|
||||
@ -130,13 +125,7 @@ class EventRepository(val context: Context) {
|
||||
}
|
||||
|
||||
fun getFutureEvents(): List<Event> {
|
||||
val now = Calendar.getInstance().timeInMillis
|
||||
realm.refresh()
|
||||
return realm
|
||||
.where(Event::class.java)
|
||||
.greaterThan("endDate", now)
|
||||
.findAll()
|
||||
.applyFilters()
|
||||
return db.dao().findFuture(Calendar.getInstance().timeInMillis).applyFilters().sortEvents()
|
||||
}
|
||||
|
||||
private fun getEvents(): List<Event> {
|
||||
@ -155,18 +144,54 @@ class EventRepository(val context: Context) {
|
||||
else -> add(Calendar.HOUR, 6)
|
||||
}
|
||||
}
|
||||
realm.refresh()
|
||||
return realm
|
||||
.where(Event::class.java)
|
||||
.greaterThan("endDate", now)
|
||||
.lessThanOrEqualTo("startDate", limit.timeInMillis)
|
||||
.findAll()
|
||||
.applyFilters()
|
||||
return db.dao().find(now, limit.timeInMillis).applyFilters().sortEvents()
|
||||
}
|
||||
|
||||
fun getEventsCount(): Int = getEvents().size
|
||||
|
||||
fun close() {
|
||||
realm.close()
|
||||
// db.close()
|
||||
}
|
||||
|
||||
@Dao
|
||||
interface EventDao {
|
||||
@Query("SELECT * FROM events WHERE id = :id LIMIT 1")
|
||||
fun findById(id: Long) : Event?
|
||||
|
||||
@Query("SELECT * FROM events WHERE end_date > :from")
|
||||
fun findFuture(from: Long) : List<Event>
|
||||
|
||||
@Query("SELECT * FROM events WHERE end_date > :from and start_date <= :to")
|
||||
fun find(from: Long, to: Long) : List<Event>
|
||||
|
||||
@Insert
|
||||
fun insertAll(events: List<Event>)
|
||||
|
||||
@Query("DELETE FROM events")
|
||||
fun deleteAll()
|
||||
}
|
||||
|
||||
@Database(entities = arrayOf(Event::class), version = 1, exportSchema = false)
|
||||
abstract class EventDatabase : RoomDatabase() {
|
||||
abstract fun dao(): EventDao
|
||||
|
||||
companion object {
|
||||
private var INSTANCE: EventDatabase? = null
|
||||
|
||||
fun getDatabase(context: Context): EventDatabase {
|
||||
// if the INSTANCE is not null, then return it,
|
||||
// if it is, then create the database
|
||||
return INSTANCE ?: synchronized(this) {
|
||||
val instance = Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
EventDatabase::class.java,
|
||||
"events"
|
||||
).allowMainThreadQueries().build()
|
||||
INSTANCE = instance
|
||||
// return instance
|
||||
instance
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -97,7 +97,7 @@ object Preferences : KotprefModel() {
|
||||
var textSecondSize by floatPref(key = "PREF_TEXT_SECOND_SIZE", default = 16f)
|
||||
var clockTextSize by floatPref(key = "PREF_TEXT_CLOCK_SIZE", default = 72f)
|
||||
var clockBottomMargin by intPref(default = Constants.ClockBottomMargin.MEDIUM.rawValue)
|
||||
var secondRowTopMargin by intPref(default = Constants.SecondRowTopMargin.NONE.rawValue)
|
||||
var secondRowTopMargin by intPref(default = Constants.SecondRowTopMargin.SMALL.rawValue)
|
||||
var showClock by booleanPref(key = "PREF_SHOW_CLOCK", default = false)
|
||||
var clockAppName by stringPref(key = "PREF_CLOCK_APP_NAME", default = "")
|
||||
var clockAppPackage by stringPref(key = "PREF_CLOCK_APP_PACKAGE", default = "")
|
||||
|
@ -17,7 +17,7 @@ object ImageHelper {
|
||||
0 -> 0f * factor
|
||||
1 -> 8f * factor
|
||||
2 -> 16f * factor
|
||||
else -> 0f * factor
|
||||
else -> 8f * factor
|
||||
}, resources.displayMetrics)
|
||||
|
||||
if (originalView.drawable != null && originalView.drawable.intrinsicWidth > 0 && originalView.drawable.intrinsicHeight > 0) {
|
||||
@ -58,7 +58,7 @@ object ImageHelper {
|
||||
0 -> 0f * factor
|
||||
1 -> 0.8f * factor
|
||||
2 -> 1f * factor
|
||||
else -> 0f
|
||||
else -> 0.8f * factor
|
||||
}))
|
||||
|
||||
colorMatrixScript.setColorMatrix(matrix)
|
||||
|
@ -339,92 +339,92 @@ object WeatherHelper {
|
||||
}
|
||||
}
|
||||
|
||||
fun getWeatherGovIcon(iconString: String, isDaytime: Boolean): String = when {
|
||||
iconString.contains("skc") -> "01"
|
||||
iconString.contains("few") -> "02"
|
||||
iconString.contains("sct") -> "03"
|
||||
iconString.contains("bkn") -> "04"
|
||||
iconString.contains("ovc") -> "04"
|
||||
iconString.contains("wind_skc") -> "01"
|
||||
iconString.contains("wind_few") -> "02"
|
||||
iconString.contains("wind_sct") -> "03"
|
||||
iconString.contains("wind_bkn") -> "04"
|
||||
iconString.contains("wind_ovc") -> "04"
|
||||
iconString.contains("snow") -> "13"
|
||||
iconString.contains("rain_snow") -> "81"
|
||||
iconString.contains("rain_sleet") -> "81"
|
||||
iconString.contains("snow_sleet") -> "81"
|
||||
iconString.contains("fzra") -> "81"
|
||||
iconString.contains("rain_fzra") -> "81"
|
||||
iconString.contains("snow_fzra") -> "81"
|
||||
iconString.contains("sleet") -> "81"
|
||||
iconString.contains("rain") -> "10"
|
||||
iconString.contains("rain_showers") -> "10"
|
||||
iconString.contains("rain_showers_hi") -> "10"
|
||||
iconString.contains("tsra") -> "82"
|
||||
iconString.contains("tsra_sct") -> "82"
|
||||
iconString.contains("tsra_hi") -> "82"
|
||||
iconString.contains("tornado") -> "80"
|
||||
iconString.contains("hurricane") -> "80"
|
||||
iconString.contains("tropical_storm") -> "09"
|
||||
iconString.contains("dust") -> "Dust"
|
||||
iconString.contains("smoke") -> "Smoke"
|
||||
iconString.contains("haze") -> "50"
|
||||
iconString.contains("hot") -> "01"
|
||||
iconString.contains("cold") -> "13"
|
||||
iconString.contains("blizzard") -> "80"
|
||||
iconString.contains("fog") -> "82"
|
||||
fun getWeatherGovIcon(iconString: String, isDaytime: Boolean): String = when (iconString.substringBefore('?').substringAfterLast('/')) {
|
||||
"skc" -> "01"
|
||||
"few" -> "02"
|
||||
"sct" -> "02"
|
||||
"bkn" -> "03"
|
||||
"ovc" -> "04"
|
||||
"wind_skc" -> "01"
|
||||
"wind_few" -> "02"
|
||||
"wind_sct" -> "02"
|
||||
"wind_bkn" -> "03"
|
||||
"wind_ovc" -> "04"
|
||||
"snow" -> "13"
|
||||
"rain_snow" -> "81"
|
||||
"rain_sleet" -> "81"
|
||||
"snow_sleet" -> "81"
|
||||
"fzra" -> "81"
|
||||
"rain_fzra" -> "81"
|
||||
"snow_fzra" -> "81"
|
||||
"sleet" -> "81"
|
||||
"rain" -> "10"
|
||||
"rain_showers" -> "10"
|
||||
"rain_showers_hi" -> "10"
|
||||
"tsra" -> "09"
|
||||
"tsra_sct" -> "11"
|
||||
"tsra_hi" -> "11"
|
||||
"tornado" -> "80"
|
||||
"hurricane" -> "80"
|
||||
"tropical_storm" -> "09"
|
||||
"dust" -> "50"
|
||||
"smoke" -> "50"
|
||||
"haze" -> "50"
|
||||
"hot" -> "01"
|
||||
"cold" -> "13"
|
||||
"blizzard" -> "13"
|
||||
"fog" -> "82"
|
||||
else -> ""
|
||||
} + if (isDaytime) "d" else "n"
|
||||
|
||||
fun getWeatherBitIcon(iconString: String): String = when {
|
||||
iconString.contains("t01") -> "11"
|
||||
iconString.contains("t02") -> "09"
|
||||
iconString.contains("t03") -> "09"
|
||||
iconString.contains("t04") -> "09"
|
||||
iconString.contains("t05") -> "09"
|
||||
iconString.contains("d01") -> "10"
|
||||
iconString.contains("d02") -> "10"
|
||||
iconString.contains("d03") -> "10"
|
||||
iconString.contains("r01") -> "10"
|
||||
iconString.contains("r02") -> "10"
|
||||
iconString.contains("r03") -> "10"
|
||||
iconString.contains("f01") -> "10"
|
||||
iconString.contains("r04") -> "10"
|
||||
iconString.contains("r05") -> "10"
|
||||
iconString.contains("r06") -> "10"
|
||||
iconString.contains("s01") -> "13"
|
||||
iconString.contains("s02") -> "13"
|
||||
iconString.contains("s03") -> "13"
|
||||
iconString.contains("s04") -> "81"
|
||||
iconString.contains("s05") -> "90"
|
||||
iconString.contains("s06") -> "13"
|
||||
iconString.contains("a01") -> "82"
|
||||
iconString.contains("a02") -> "82"
|
||||
iconString.contains("a03") -> "82"
|
||||
iconString.contains("a04") -> "82"
|
||||
iconString.contains("a05") -> "82"
|
||||
iconString.contains("a06") -> "82"
|
||||
iconString.contains("c01") -> "01"
|
||||
iconString.contains("c02") -> "02"
|
||||
iconString.contains("c03") -> "04"
|
||||
iconString.contains("c04") -> "04"
|
||||
fun getWeatherBitIcon(iconString: String): String = when (iconString.substring(0, 3)) {
|
||||
"t01" -> "11"
|
||||
"t02" -> "11"
|
||||
"t03" -> "09"
|
||||
"t04" -> "11"
|
||||
"t05" -> "11"
|
||||
"d01" -> "10"
|
||||
"d02" -> "10"
|
||||
"d03" -> "10"
|
||||
"r01" -> "10"
|
||||
"r02" -> "10"
|
||||
"r03" -> "10"
|
||||
"f01" -> "10"
|
||||
"r04" -> "10"
|
||||
"r05" -> "10"
|
||||
"r06" -> "10"
|
||||
"s01" -> "13"
|
||||
"s02" -> "13"
|
||||
"s03" -> "13"
|
||||
"s04" -> "81"
|
||||
"s05" -> "81"
|
||||
"s06" -> "13"
|
||||
"a01" -> "50"
|
||||
"a02" -> "50"
|
||||
"a03" -> "50"
|
||||
"a04" -> "50"
|
||||
"a05" -> "82"
|
||||
"a06" -> "82"
|
||||
"c01" -> "01"
|
||||
"c02" -> "02"
|
||||
"c03" -> "03"
|
||||
"c04" -> "04"
|
||||
else -> ""
|
||||
} + if (iconString.contains("d")) "d" else "n"
|
||||
} + iconString.substring(3)
|
||||
|
||||
fun getWeatherApiIcon(icon: Int, isDaytime: Boolean): String = when(icon) {
|
||||
1000 -> "01"
|
||||
1003 -> "02"
|
||||
1006 -> "03"
|
||||
1009 -> "04"
|
||||
1030 -> "82"
|
||||
1030 -> "50"
|
||||
1063 -> "10"
|
||||
1066 -> "10"
|
||||
1069 -> "10"
|
||||
1066 -> "13"
|
||||
1069 -> "81"
|
||||
1072 -> "81"
|
||||
1087 -> "11"
|
||||
1114 -> "13"
|
||||
1117 -> "09"
|
||||
1117 -> "13"
|
||||
1135 -> "82"
|
||||
1147 -> "82"
|
||||
1150 -> "10"
|
||||
@ -439,8 +439,8 @@ object WeatherHelper {
|
||||
1195 -> "10"
|
||||
1198 -> "81"
|
||||
1201 -> "81"
|
||||
1204 -> "13"
|
||||
1207 -> "13"
|
||||
1204 -> "81"
|
||||
1207 -> "81"
|
||||
1210 -> "13"
|
||||
1213 -> "13"
|
||||
1216 -> "13"
|
||||
@ -451,62 +451,62 @@ object WeatherHelper {
|
||||
1240 -> "10"
|
||||
1243 -> "10"
|
||||
1246 -> "10"
|
||||
1249 -> "13"
|
||||
1252 -> "13"
|
||||
1249 -> "81"
|
||||
1252 -> "81"
|
||||
1255 -> "13"
|
||||
1258 -> "13"
|
||||
1261 -> "13"
|
||||
1264 -> "13"
|
||||
1273 -> "09"
|
||||
1273 -> "11"
|
||||
1276 -> "09"
|
||||
1279 -> "13"
|
||||
1282 -> "13"
|
||||
else -> ""
|
||||
} + if (isDaytime) "d" else "n"
|
||||
|
||||
fun getYRIcon(iconCode: String, isDaytime: Boolean): String = when {
|
||||
iconCode.contains("clearsky") -> "01"
|
||||
iconCode.contains("cloudy") -> "04"
|
||||
iconCode.contains("fair") -> "02"
|
||||
iconCode.contains("fog") -> "82"
|
||||
iconCode.contains("heavyrain") -> "10"
|
||||
iconCode.contains("heavyrainandthunder") -> "11"
|
||||
iconCode.contains("heavyrainshowers") -> "10"
|
||||
iconCode.contains("heavyrainshowersandthunder") -> "11"
|
||||
iconCode.contains("heavysleet") -> "10"
|
||||
iconCode.contains("heavysleetandthunder") -> "11"
|
||||
iconCode.contains("heavysleetshowers") -> "10"
|
||||
iconCode.contains("heavysleetshowersandthunder") -> "11"
|
||||
iconCode.contains("heavysnow") -> "13"
|
||||
iconCode.contains("heavysnowandthunder") -> "13"
|
||||
iconCode.contains("heavysnowshowers") -> "13"
|
||||
iconCode.contains("heavysnowshowersandthunder") -> "13"
|
||||
iconCode.contains("lightrain") -> "10"
|
||||
iconCode.contains("lightrainandthunder") -> "11"
|
||||
iconCode.contains("lightrainshowers") -> "10"
|
||||
iconCode.contains("lightrainshowersandthunder") -> "11"
|
||||
iconCode.contains("lightsleet") -> "10"
|
||||
iconCode.contains("lightsleetandthunder") -> "11"
|
||||
iconCode.contains("lightsleetshowers") -> "10"
|
||||
iconCode.contains("lightsnow") -> "13"
|
||||
iconCode.contains("lightsnowandthunder") -> "13"
|
||||
iconCode.contains("lightsnowshowers") -> "13"
|
||||
iconCode.contains("lightssleetshowersandthunder") -> "81"
|
||||
iconCode.contains("lightssnowshowersandthunder") -> "81"
|
||||
iconCode.contains("partlycloudy") -> "03"
|
||||
iconCode.contains("rain") -> "10"
|
||||
iconCode.contains("rainandthunder") -> "11"
|
||||
iconCode.contains("rainshowers") -> "10"
|
||||
iconCode.contains("rainshowersandthunder") -> "11"
|
||||
iconCode.contains("sleet") -> "10"
|
||||
iconCode.contains("sleetandthunder") -> "11"
|
||||
iconCode.contains("sleetshowers") -> "10"
|
||||
iconCode.contains("sleetshowersandthunder") -> "11"
|
||||
iconCode.contains("snow") -> "13"
|
||||
iconCode.contains("snowandthunder") -> "13"
|
||||
iconCode.contains("snowshowers") -> "13"
|
||||
iconCode.contains("snowshowersandthunder") -> "13"
|
||||
fun getYRIcon(iconCode: String): String = when (iconCode.substringBefore('_')) {
|
||||
"clearsky" -> "01"
|
||||
"cloudy" -> "04"
|
||||
"fair" -> "02"
|
||||
"fog" -> "82"
|
||||
"heavyrain" -> "10"
|
||||
"heavyrainandthunder" -> "09"
|
||||
"heavyrainshowers" -> "10"
|
||||
"heavyrainshowersandthunder" -> "09"
|
||||
"heavysleet" -> "81"
|
||||
"heavysleetandthunder" -> "81"
|
||||
"heavysleetshowers" -> "81"
|
||||
"heavysleetshowersandthunder" -> "81"
|
||||
"heavysnow" -> "13"
|
||||
"heavysnowandthunder" -> "13"
|
||||
"heavysnowshowers" -> "13"
|
||||
"heavysnowshowersandthunder" -> "13"
|
||||
"lightrain" -> "10"
|
||||
"lightrainandthunder" -> "11"
|
||||
"lightrainshowers" -> "10"
|
||||
"lightrainshowersandthunder" -> "11"
|
||||
"lightsleet" -> "81"
|
||||
"lightsleetandthunder" -> "81"
|
||||
"lightsleetshowers" -> "81"
|
||||
"lightsnow" -> "13"
|
||||
"lightsnowandthunder" -> "13"
|
||||
"lightsnowshowers" -> "13"
|
||||
"lightssleetshowersandthunder" -> "81"
|
||||
"lightssnowshowersandthunder" -> "81"
|
||||
"partlycloudy" -> "03"
|
||||
"rain" -> "10"
|
||||
"rainandthunder" -> "11"
|
||||
"rainshowers" -> "10"
|
||||
"rainshowersandthunder" -> "11"
|
||||
"sleet" -> "81"
|
||||
"sleetandthunder" -> "81"
|
||||
"sleetshowers" -> "81"
|
||||
"sleetshowersandthunder" -> "81"
|
||||
"snow" -> "13"
|
||||
"snowandthunder" -> "13"
|
||||
"snowshowers" -> "13"
|
||||
"snowshowersandthunder" -> "13"
|
||||
else -> ""
|
||||
} + if (isDaytime) "d" else "n"
|
||||
} + if (iconCode.substringAfter('_', "day") == "day") "d" else "n"
|
||||
|
||||
}
|
@ -1,26 +1,35 @@
|
||||
package com.tommasoberlose.anotherwidget.models
|
||||
|
||||
import android.provider.CalendarContract
|
||||
import io.realm.RealmObject
|
||||
import java.util.Date
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
/**
|
||||
* Created by tommaso on 05/10/17.
|
||||
*/
|
||||
|
||||
open class Event(
|
||||
var id: Long = 0,
|
||||
var eventID: Long = 0,
|
||||
var title: String = "",
|
||||
var startDate: Long = 0,
|
||||
var endDate: Long = 0,
|
||||
var calendarID: Int = 0,
|
||||
var allDay: Boolean = false,
|
||||
var address: String = "",
|
||||
var selfAttendeeStatus: Int = CalendarContract.Attendees.ATTENDEE_STATUS_NONE,
|
||||
var availability: Int = CalendarContract.EventsEntity.AVAILABILITY_BUSY
|
||||
) : RealmObject() {
|
||||
@Entity(tableName = "events")
|
||||
data class Event(
|
||||
@PrimaryKey
|
||||
val id: Long = 0,
|
||||
@ColumnInfo(name = "event_id")
|
||||
val eventID: Long = 0,
|
||||
val title: String = "",
|
||||
@ColumnInfo(name = "start_date")
|
||||
val startDate: Long = 0,
|
||||
@ColumnInfo(name = "end_date")
|
||||
val endDate: Long = 0,
|
||||
@ColumnInfo(name = "calendar_id")
|
||||
val calendarID: Long = 0,
|
||||
@ColumnInfo(name = "all_day")
|
||||
val allDay: Boolean = false,
|
||||
val address: String = "",
|
||||
@ColumnInfo(name = "self_attendee_status")
|
||||
val selfAttendeeStatus: Int = CalendarContract.Attendees.ATTENDEE_STATUS_NONE,
|
||||
val availability: Int = CalendarContract.EventsEntity.AVAILABILITY_BUSY
|
||||
)/* {
|
||||
override fun toString(): String {
|
||||
return "Event:\nEVENT ID: " + eventID + "\nTITLE: " + title + "\nSTART DATE: " + Date(startDate) + "\nEND DATE: " + Date(endDate) + "\nCAL ID: " + calendarID + "\nADDRESS: " + address
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
@ -26,9 +26,7 @@ class TimeZonesApi(val context: Context) {
|
||||
when (val response = repository.getTimeZone(lat, long)) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
Log.d("ciao", response.body.toString())
|
||||
id = response.body["timezoneId"] as String
|
||||
|
||||
} catch(ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
|
@ -121,8 +121,17 @@ class WeatherNetworkApi(val context: Context) {
|
||||
val props =
|
||||
weatherResponse.body["properties"] as LinkedTreeMap<*, *>
|
||||
val periods = props["periods"] as List<*>
|
||||
val now = periods[0] as LinkedTreeMap<*, *>
|
||||
|
||||
@android.annotation.SuppressLint("SimpleDateFormat")
|
||||
val format = SimpleDateFormat(
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N)
|
||||
"yyyy-MM-dd'T'HH:mm:ssXXX"
|
||||
else
|
||||
"yyyy-MM-dd'T'HH:mm:ssZ"
|
||||
)
|
||||
for (period in periods) {
|
||||
val now = period as LinkedTreeMap<*, *>
|
||||
val endTime = format.parse(now["endTime"] as String)!!
|
||||
if (endTime.time > System.currentTimeMillis()) {
|
||||
val temp = now["temperature"] as Double
|
||||
val fullIcon = now["icon"] as String
|
||||
val isDaytime = now["isDaytime"] as Boolean
|
||||
@ -130,16 +139,16 @@ class WeatherNetworkApi(val context: Context) {
|
||||
Preferences.weatherTemp = temp.toFloat()
|
||||
Preferences.weatherIcon = WeatherHelper.getWeatherGovIcon(fullIcon, isDaytime)
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
MainWidget.updateWidget(context)
|
||||
break
|
||||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} finally {
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
@ -155,14 +164,16 @@ class WeatherNetworkApi(val context: Context) {
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
if (pointsResponse.body?.containsKey("status") == true && (pointsResponse.body?.get("status") as Double).toInt() == 404) {
|
||||
when (pointsResponse.code) {
|
||||
404 -> {
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_wrong_location)
|
||||
} else {
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
|
||||
}
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
@ -183,7 +194,18 @@ class WeatherNetworkApi(val context: Context) {
|
||||
when (val response = repository.getWeather()) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
Log.d("ciao - here", response.body.toString())
|
||||
val observations = response.body["observations"] as LinkedTreeMap<*, *>
|
||||
val location = (observations["location"] as List<*>).first() as LinkedTreeMap<*, *>
|
||||
val observation = (location["observation"] as List<*>).first() as LinkedTreeMap<*, *>
|
||||
val iconName = observation["iconName"] as String
|
||||
val daylight = observation["daylight"] as String
|
||||
val temperature = observation["temperature"] as String
|
||||
|
||||
Preferences.weatherTemp = temperature.toFloat()
|
||||
Preferences.weatherIcon = repository.getWeatherIcon(iconName, daylight != "N")
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} catch(ex: Exception) {
|
||||
@ -194,8 +216,16 @@ class WeatherNetworkApi(val context: Context) {
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
when (response.code) {
|
||||
401 -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_invalid_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
}
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
@ -225,10 +255,10 @@ class WeatherNetworkApi(val context: Context) {
|
||||
when (val response = repository.getWeather()) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val data = response.body["data"] as List<LinkedTreeMap<String, Any>>?
|
||||
data?.first()?.let {
|
||||
val data = response.body["data"] as List<*>?
|
||||
data?.first()?.let { it as LinkedTreeMap<*, *>
|
||||
val temp = it["temp"] as Double
|
||||
val weatherInfo = it["weather"] as LinkedTreeMap<String, Any>
|
||||
val weatherInfo = it["weather"] as LinkedTreeMap<*, *>
|
||||
val iconCode = weatherInfo["icon"] as String
|
||||
|
||||
Preferences.weatherTemp = temp.toFloat()
|
||||
@ -238,8 +268,6 @@ class WeatherNetworkApi(val context: Context) {
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
} catch(ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
@ -288,12 +316,12 @@ class WeatherNetworkApi(val context: Context) {
|
||||
when (val response = repository.getWeather()) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val current = response.body["current"] as LinkedTreeMap<String, Any>?
|
||||
val current = response.body["current"] as LinkedTreeMap<*, *>?
|
||||
current?.let {
|
||||
val tempC = current["temp_c"] as Double
|
||||
val tempF = current["temp_f"] as Double
|
||||
val isDay = current["is_day"] as Double
|
||||
val condition = current["condition"] as LinkedTreeMap<String, Any>
|
||||
val condition = current["condition"] as LinkedTreeMap<*, *>
|
||||
val iconCode = condition["code"] as Double
|
||||
|
||||
Preferences.weatherTemp = if (Preferences.weatherTempUnit == "F") tempF.toFloat() else tempC.toFloat()
|
||||
@ -303,8 +331,6 @@ class WeatherNetworkApi(val context: Context) {
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
} catch(ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
@ -353,28 +379,74 @@ class WeatherNetworkApi(val context: Context) {
|
||||
|
||||
private suspend fun useAccuweatherProvider(context: Context) {
|
||||
if (Preferences.weatherProviderApiAccuweather != "") {
|
||||
// val repository = AccuweatherRepository()
|
||||
val repository = AccuweatherRepository()
|
||||
|
||||
// when (val response = repository.getWeather()) {
|
||||
// is NetworkResponse.Success -> {
|
||||
// try {
|
||||
// Log.d("ciao", response.body.toString())
|
||||
// } catch(ex: Exception) {
|
||||
//
|
||||
// Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
// Preferences.weatherProviderLocationError = ""
|
||||
// }
|
||||
// }
|
||||
// is NetworkResponse.ServerError -> {
|
||||
// WeatherHelper.removeWeather(
|
||||
// context
|
||||
// )
|
||||
// }
|
||||
// Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
// Preferences.weatherProviderLocationError = ""
|
||||
// EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
// }
|
||||
when (val locationResponse = repository.getLocation()) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val key = locationResponse.body["Key"] as String
|
||||
|
||||
when (val weatherResponse = repository.getWeather(key)) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
weatherResponse.body.first().let {
|
||||
val temp = it["Temperature"] as LinkedTreeMap<*, *>
|
||||
val tempC = (temp["Metric"] as LinkedTreeMap<*, *>)["Value"] as Double
|
||||
val tempF = (temp["Imperial"] as LinkedTreeMap<*, *>)["Value"] as Double
|
||||
val isDay = it["IsDayTime"] as Boolean
|
||||
val icon = it["WeatherIcon"] as Double
|
||||
|
||||
Preferences.weatherTemp = if (Preferences.weatherTempUnit == "F") tempF.toFloat() else tempC.toFloat()
|
||||
Preferences.weatherIcon = repository.getWeatherIcon(icon.toInt(), isDay)
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
}
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} catch (ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
}
|
||||
} catch(ex: Exception) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
} finally {
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
is NetworkResponse.ServerError -> {
|
||||
when (locationResponse.code) {
|
||||
401 -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_invalid_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
503 -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_expired_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
}
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
@ -393,14 +465,9 @@ class WeatherNetworkApi(val context: Context) {
|
||||
is NetworkResponse.Success -> {
|
||||
try {
|
||||
val pp = response.body["properties"] as LinkedTreeMap<*, *>
|
||||
val data = pp["timeseries"] as List<LinkedTreeMap<String, Any>>?
|
||||
data?.let {
|
||||
val format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||
for (item in data) {
|
||||
val time = Calendar.getInstance().apply { time = format.parse(item["time"] as String)!! }
|
||||
val now = Calendar.getInstance()
|
||||
if (time.timeInMillis >= now.timeInMillis) {
|
||||
val dd = item["data"] as LinkedTreeMap<*, *>
|
||||
val data = pp["timeseries"] as List<*>?
|
||||
data?.first()?.let { it as LinkedTreeMap<*, *>
|
||||
val dd = it["data"] as LinkedTreeMap<*, *>
|
||||
val instant = dd["instant"] as LinkedTreeMap<*, *>
|
||||
val next = dd["next_1_hours"] as LinkedTreeMap<*, *>
|
||||
|
||||
@ -411,20 +478,14 @@ class WeatherNetworkApi(val context: Context) {
|
||||
val iconCode = summary["symbol_code"] as String
|
||||
|
||||
Preferences.weatherTemp = temp.toFloat()
|
||||
Preferences.weatherIcon = WeatherHelper.getYRIcon(iconCode, now.get(Calendar.HOUR_OF_DAY) >= 22 || now.get(Calendar.HOUR_OF_DAY) <= 8)
|
||||
Preferences.weatherIcon = WeatherHelper.getYRIcon(iconCode)
|
||||
Preferences.weatherTempUnit = "C"
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} catch(ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
|
@ -13,7 +13,7 @@ object ApiServices {
|
||||
): NetworkResponse<HashMap<String, Any>, HashMap<String, Any>>
|
||||
|
||||
@Headers("User-Agent: (Another Widget, tommaso.berlose@gmail.com)")
|
||||
@GET("gridpoints/{gridId}/{gridX},{gridY}/forecast")
|
||||
@GET("gridpoints/{gridId}/{gridX},{gridY}/forecast/hourly")
|
||||
suspend fun getWeather(
|
||||
@Path("gridId") gridId: String,
|
||||
@Path("gridX") gridX: Int,
|
||||
@ -54,13 +54,17 @@ object ApiServices {
|
||||
}
|
||||
|
||||
interface AccuweatherService {
|
||||
@GET("")
|
||||
suspend fun getWeather(
|
||||
@Path("gridId") gridId: String,
|
||||
@Path("gridX") gridX: Int,
|
||||
@Path("gridY") gridY: Int,
|
||||
@Query("units") unit: String
|
||||
@GET("locations/v1/cities/geoposition/search")
|
||||
suspend fun getLocation(
|
||||
@Query("apikey") apikey: String,
|
||||
@Query("q") location: String
|
||||
): NetworkResponse<HashMap<String, Any>, HashMap<String, Any>>
|
||||
|
||||
@GET("currentconditions/v1/{locationKey}")
|
||||
suspend fun getWeather(
|
||||
@Path("locationKey") locationKey: String,
|
||||
@Query("apikey") apikey: String
|
||||
): NetworkResponse<List<HashMap<String, Any>>, HashMap<String, Any>>
|
||||
}
|
||||
|
||||
interface YrService {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.tommasoberlose.anotherwidget.network.repository
|
||||
|
||||
import com.haroldadmin.cnradapter.NetworkResponseAdapterFactory
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.network.api.ApiServices
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
@ -9,10 +10,11 @@ class AccuweatherRepository {
|
||||
|
||||
/* ACCUWEATHER */
|
||||
private val apiServiceAccu: ApiServices.AccuweatherService = getRetrofit().create(ApiServices.AccuweatherService::class.java)
|
||||
suspend fun getWeather(): Nothing = TODO()
|
||||
suspend fun getLocation() = apiServiceAccu.getLocation(Preferences.weatherProviderApiAccuweather, "${Preferences.customLocationLat},${Preferences.customLocationLon}")
|
||||
suspend fun getWeather(locationKey: String) = apiServiceAccu.getWeather(locationKey, Preferences.weatherProviderApiAccuweather)
|
||||
|
||||
companion object {
|
||||
private const val BASE_URL_ACCU = ""
|
||||
private const val BASE_URL_ACCU = "https://dataservice.accuweather.com/"
|
||||
|
||||
private fun getRetrofit(): Retrofit {
|
||||
return Retrofit.Builder()
|
||||
@ -22,4 +24,20 @@ class AccuweatherRepository {
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
fun getWeatherIcon(icon: Int, isDaytime: Boolean): String = when(icon) {
|
||||
1, 2, 30, 33, 34 -> "01"
|
||||
3, 4, 35, 36 -> "02"
|
||||
5, 37 -> "50"
|
||||
6, 38 -> "03"
|
||||
7, 8 -> "04"
|
||||
11 -> "82"
|
||||
12, 13, 14, 18, 39, 40 -> "10"
|
||||
15 -> "09"
|
||||
16, 17, 41, 42 -> "11"
|
||||
32 -> "80"
|
||||
19, 20, 21, 22, 23, 24, 31, 43, 44 -> "13"
|
||||
25, 26, 29 -> "81"
|
||||
else -> ""
|
||||
} + if (isDaytime) "d" else "n"
|
||||
}
|
@ -23,4 +23,157 @@ class HereRepository {
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
fun getWeatherIcon(iconName: String, isDaytime: Boolean): String = when(iconName.substringAfter("night_")) {
|
||||
"sunny" -> "01"
|
||||
"clear" -> "01"
|
||||
"mostly_sunny" -> "01"
|
||||
"mostly_clear" -> "01"
|
||||
"passing_clounds" -> "02"
|
||||
"more_sun_than_clouds" -> "02"
|
||||
"scattered_clouds" -> "02"
|
||||
"partly_cloudy" -> "02"
|
||||
"a_mixture_of_sun_and_clouds" -> "03"
|
||||
"increasing_cloudiness" -> "03"
|
||||
"breaks_of_sun_late" -> "03"
|
||||
"afternoon_clouds" -> "03"
|
||||
"morning_clouds" -> "03"
|
||||
"partly_sunny" -> "03"
|
||||
"high_level_clouds" -> "03"
|
||||
"decreasing_cloudiness" -> "03"
|
||||
"clearing_skies" -> "01"
|
||||
"high_clouds" -> "03"
|
||||
"rain_early" -> "10"
|
||||
"heavy_rain_early" -> "10"
|
||||
"strong_thunderstorms" -> "09"
|
||||
"severe_thunderstorms" -> "09"
|
||||
"thundershowers" -> "11"
|
||||
"thunderstorms" -> "11"
|
||||
"tstorms_early" -> "11"
|
||||
"isolated_tstorms_late" -> "11"
|
||||
"scattered_tstorms_late" -> "11"
|
||||
"tstorms_late" -> "11"
|
||||
"tstorms" -> "11"
|
||||
"ice_fog" -> "82"
|
||||
"more_clouds_than_sun" -> "03"
|
||||
"broken_clouds" -> "03"
|
||||
"scattered_showers" -> "10"
|
||||
"a_few_showers" -> "10"
|
||||
"light_showers" -> "10"
|
||||
"passing_showers" -> "10"
|
||||
"rain_showers" -> "10"
|
||||
"showers" -> "10"
|
||||
"widely_scattered_tstorms" -> "11"
|
||||
"isolated_tstorms" -> "11"
|
||||
"a_few_tstorms" -> "11"
|
||||
"scattered_tstorms" -> "11"
|
||||
"hazy_sunshine" -> "50"
|
||||
"haze" -> "50"
|
||||
"smoke" -> "50"
|
||||
"low_level_haze" -> "50"
|
||||
"early_fog_followed_by_sunny_skies" -> "50"
|
||||
"early_fog" -> "82"
|
||||
"light_fog" -> "82"
|
||||
"fog" -> "82"
|
||||
"dense_fog" -> "82"
|
||||
//"night_haze"
|
||||
//"night_smoke"
|
||||
//"night_low_level_haze"
|
||||
//"night_widely_scattered_tstorms"
|
||||
//"night_isolated_tstorms"
|
||||
//"night_a_few_tstorms"
|
||||
//"night_scattered_tstorms"
|
||||
//"night_tstorms"
|
||||
//"night_clear"
|
||||
"mostly_cloudy" -> "03"
|
||||
"cloudy" -> "04"
|
||||
"overcast" -> "04"
|
||||
"low_clouds" -> "03"
|
||||
"hail" -> "10"
|
||||
"sleet" -> "81"
|
||||
"light_mixture_of_precip" -> "81"
|
||||
"icy_mix" -> "81"
|
||||
"mixture_of_precip" -> "81"
|
||||
"heavy_mixture_of_precip" -> "81"
|
||||
"snow_changing_to_rain" -> "81"
|
||||
"snow_changing_to_an_icy_mix" -> "81"
|
||||
"an_icy_mix_changing_to_snow" -> "81"
|
||||
"an_icy_mix_changing_to_rain" -> "81"
|
||||
"rain_changing_to_snow" -> "81"
|
||||
"rain_changing_to_an_icy_mix" -> "81"
|
||||
"light_icy_mix_early" -> "81"
|
||||
"icy_mix_early" -> "81"
|
||||
"light_icy_mix_late" -> "81"
|
||||
"icy_mix_late" -> "81"
|
||||
"snow_rain_mix" -> "81"
|
||||
"scattered_flurries" -> "13"
|
||||
"snow_flurries" -> "13"
|
||||
"light_snow_showers" -> "13"
|
||||
"snow_showers" -> "13"
|
||||
"light_snow" -> "13"
|
||||
"flurries_early" -> "13"
|
||||
"snow_showers_early" -> "13"
|
||||
"light_snow_early" -> "13"
|
||||
"flurries_late" -> "13"
|
||||
"snow_showers_late" -> "13"
|
||||
"light_snow_late" -> "13"
|
||||
//"night_decreasing_cloudiness"
|
||||
//"night_clearing_skies"
|
||||
//"night_high_level_clouds"
|
||||
//"night_high_clouds"
|
||||
//"night_scattered_showers"
|
||||
//"night_a_few_showers"
|
||||
//"night_light_showers"
|
||||
//"night_passing_showers"
|
||||
//"night_rain_showers"
|
||||
//"night_sprinkles"
|
||||
//"night_showers"
|
||||
//"night_mostly_clear"
|
||||
//"night_passing_clouds"
|
||||
//"night_scattered_clouds"
|
||||
//"night_partly_cloudy"
|
||||
//"increasing_cloudiness"
|
||||
//"night_afternoon_clouds"
|
||||
//"night_morning_clouds"
|
||||
//"night_broken_clouds"
|
||||
//"night_mostly_cloudy"
|
||||
"light_freezing_rain" -> "81"
|
||||
"freezing_rain" -> "81"
|
||||
"heavy_rain" -> "10"
|
||||
"lots_of_rain" -> "10"
|
||||
"tons_of_rain" -> "10"
|
||||
//"heavy_rain_early" -> "10"
|
||||
"heavy_rain_late" -> "10"
|
||||
"flash_floods" -> "10"
|
||||
"flood" -> "10"
|
||||
"drizzle" -> "10"
|
||||
"sprinkles" -> "10"
|
||||
"light_rain" -> "10"
|
||||
"sprinkles_early" -> "10"
|
||||
"light_rain_early" -> "10"
|
||||
"sprinkles_late" -> "10"
|
||||
"light_rain_late" -> "10"
|
||||
"rain" -> "10"
|
||||
"numerous_showers" -> "10"
|
||||
"showery" -> "10"
|
||||
"showers_early" -> "10"
|
||||
//"rain_early" -> "10"
|
||||
"showers_late" -> "10"
|
||||
"rain_late" -> "10"
|
||||
"snow" -> "13"
|
||||
"moderate_snow" -> "13"
|
||||
"snow_early" -> "13"
|
||||
"snow_late" -> "13"
|
||||
"heavy_snow" -> "13"
|
||||
"heavy_snow_early" -> "13"
|
||||
"heavy_snow_late" -> "13"
|
||||
"tornado" -> "80"
|
||||
"tropical_storm" -> "09"
|
||||
"hurricane" -> "80"
|
||||
"sandstorm" -> "50"
|
||||
"duststorm" -> "50"
|
||||
"snowstorm" -> "13"
|
||||
"blizzard" -> "13"
|
||||
else -> ""
|
||||
} + if (isDaytime) "d" else "n"
|
||||
}
|
@ -95,7 +95,7 @@ class UpdatesReceiver : BroadcastReceiver() {
|
||||
setEventUpdate(context, event)
|
||||
}
|
||||
} else {
|
||||
val event = eventRepository.getEventByEventId(eventId)
|
||||
val event = eventRepository.getEventById(eventId)
|
||||
if (event != null) {
|
||||
setEventUpdate(context, event)
|
||||
}
|
||||
@ -166,11 +166,11 @@ class UpdatesReceiver : BroadcastReceiver() {
|
||||
fireTime.coerceAtLeast(now.timeInMillis + 1000 * 60),
|
||||
PendingIntent.getBroadcast(
|
||||
context,
|
||||
event.eventID.toInt(),
|
||||
event.id.toInt(),
|
||||
Intent(context, UpdatesReceiver::class.java).apply {
|
||||
action = Actions.ACTION_TIME_UPDATE
|
||||
if (event.startDate > now.timeInMillis)
|
||||
putExtra(EVENT_ID, event.eventID)
|
||||
putExtra(EVENT_ID, event.id)
|
||||
},
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
@ -185,7 +185,7 @@ class UpdatesReceiver : BroadcastReceiver() {
|
||||
}, 0))
|
||||
val eventRepository = EventRepository(context)
|
||||
eventRepository.getFutureEvents().forEach {
|
||||
cancel(PendingIntent.getBroadcast(context, it.eventID.toInt(), Intent(context, UpdatesReceiver::class.java).apply {
|
||||
cancel(PendingIntent.getBroadcast(context, it.id.toInt(), Intent(context, UpdatesReceiver::class.java).apply {
|
||||
action = Actions.ACTION_TIME_UPDATE
|
||||
}, 0))
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ class UpdateCalendarService : Service() {
|
||||
title = e.title ?: "",
|
||||
startDate = instance.begin,
|
||||
endDate = instance.end,
|
||||
calendarID = e.calendarId.toInt(),
|
||||
calendarID = e.calendarId,
|
||||
allDay = e.allDay,
|
||||
address = e.eventLocation ?: "",
|
||||
selfAttendeeStatus = e.selfAttendeeStatus.toInt(),
|
||||
|
@ -115,8 +115,6 @@ class WeatherProviderActivity : AppCompatActivity() {
|
||||
|
||||
adapter.updateData(
|
||||
Constants.WeatherProvider.values().asList()
|
||||
.filter { it != Constants.WeatherProvider.HERE }
|
||||
.filter { it != Constants.WeatherProvider.ACCUWEATHER }
|
||||
)
|
||||
|
||||
setupListener()
|
||||
@ -165,7 +163,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onMessageEvent(ignore: MainFragment.UpdateUiMessageEvent?) {
|
||||
fun onMessageEvent(@Suppress("UNUSED_PARAMETER") ignore: MainFragment.UpdateUiMessageEvent?) {
|
||||
binding.loader.isVisible = Preferences.weatherProviderError == "-"
|
||||
if (Preferences.weatherProviderError == "" && Preferences.weatherProviderLocationError == "") {
|
||||
Snackbar.make(binding.listView, getString(R.string.settings_weather_provider_api_key_subtitle_all_set), Snackbar.LENGTH_LONG).show()
|
||||
|
@ -86,6 +86,7 @@ class MainFragment : Fragment() {
|
||||
binding.actionSettings.isClickable = !show
|
||||
binding.actionSettings.isFocusable = !show
|
||||
binding.fragmentTitle.text = if (show) destination.label.toString() else getString(R.string.app_name)
|
||||
binding.toolbar.cardElevation = 0f
|
||||
}
|
||||
|
||||
binding.actionSettings.setOnSingleClickListener {
|
||||
@ -98,6 +99,10 @@ class MainFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun subscribeUi(viewModel: MainViewModel) {
|
||||
viewModel.showPreview.observe(viewLifecycleOwner) {
|
||||
binding.preview.visibility = if (it) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
viewModel.showWallpaper.observe(viewLifecycleOwner) {
|
||||
if (it) {
|
||||
val wallpaper = requireActivity().getCurrentWallpaper()
|
||||
@ -138,7 +143,7 @@ class MainFragment : Fragment() {
|
||||
}
|
||||
|
||||
viewModel.fragmentScrollY.observe(viewLifecycleOwner) {
|
||||
binding.toolbar.cardElevation = if (it > 0) 24f else 0f
|
||||
binding.toolbar.cardElevation = if (it > 0) 32f else 0f
|
||||
}
|
||||
|
||||
viewModel.widgetPreferencesUpdate.observe(viewLifecycleOwner) {
|
||||
@ -218,7 +223,7 @@ class MainFragment : Fragment() {
|
||||
class ChangeTabEvent(val page: Int)
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onUpdateUiEvent(ignore: UpdateUiMessageEvent?) {
|
||||
fun onUpdateUiEvent(@Suppress("UNUSED_PARAMETER") ignore: UpdateUiMessageEvent?) {
|
||||
delayJob?.cancel()
|
||||
delayJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||
delay(300)
|
||||
@ -229,7 +234,7 @@ class MainFragment : Fragment() {
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onChangeTabEvent(ignore: ChangeTabEvent) {
|
||||
fun onChangeTabEvent(@Suppress("UNUSED_PARAMETER") ignore: ChangeTabEvent) {
|
||||
val navHost = childFragmentManager.findFragmentById(R.id.settings_fragment) as? NavHostFragment?
|
||||
navHost?.navController?.navigateUp()
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import com.tommasoberlose.anotherwidget.receivers.WidgetClickListenerReceiver
|
||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||
import com.tommasoberlose.anotherwidget.utils.convertDpToPixel
|
||||
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||
import java.text.DateFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -875,24 +876,24 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
||||
val shadowRadius =
|
||||
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||
0 -> 0f
|
||||
1 -> 5f
|
||||
2 -> 5f
|
||||
else -> 5f
|
||||
}
|
||||
1 -> 2f
|
||||
2 -> 3f
|
||||
else -> 2f
|
||||
}.toPixel(context)
|
||||
val shadowColor =
|
||||
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||
0 -> Color.TRANSPARENT
|
||||
1 -> R.color.black_50
|
||||
1 -> Color.DKGRAY
|
||||
2 -> Color.BLACK
|
||||
else -> R.color.black_50
|
||||
else -> Color.DKGRAY
|
||||
}
|
||||
val shadowDy =
|
||||
val shadowOffset =
|
||||
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||
0 -> 0f
|
||||
1 -> 0f
|
||||
2 -> 1f
|
||||
2 -> 0.5f
|
||||
else -> 0f
|
||||
}
|
||||
}.toPixel(context)
|
||||
|
||||
listOf<TextView>(
|
||||
bindingView.date,
|
||||
@ -903,7 +904,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
||||
bindingView.weatherSubLineDivider,
|
||||
bindingView.weatherSubLineTemperature,
|
||||
).forEach {
|
||||
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
it.setShadowLayer(shadowRadius, shadowOffset, shadowOffset, shadowColor)
|
||||
}
|
||||
|
||||
// Icons shadow
|
||||
@ -917,7 +918,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
||||
it.second.isVisible = it.first.isVisible
|
||||
it.second.scaleX = it.first.scaleX
|
||||
it.second.scaleY = it.first.scaleY
|
||||
it.second.applyShadow(it.first, 0.7f)
|
||||
it.second.applyShadow(it.first, 0.8f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -912,24 +912,24 @@ class StandardWidget(val context: Context) {
|
||||
val shadowRadius =
|
||||
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||
0 -> 0f
|
||||
1 -> 5f
|
||||
2 -> 5f
|
||||
else -> 5f
|
||||
}
|
||||
1 -> 2f
|
||||
2 -> 3f
|
||||
else -> 2f
|
||||
}.toPixel(context)
|
||||
val shadowColor =
|
||||
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||
0 -> Color.TRANSPARENT
|
||||
1 -> R.color.black_50
|
||||
1 -> Color.DKGRAY
|
||||
2 -> Color.BLACK
|
||||
else -> R.color.black_50
|
||||
else -> Color.DKGRAY
|
||||
}
|
||||
val shadowDy =
|
||||
val shadowOffset =
|
||||
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||
0 -> 0f
|
||||
1 -> 0f
|
||||
2 -> 1f
|
||||
2 -> 0.5f
|
||||
else -> 0f
|
||||
}
|
||||
}.toPixel(context)
|
||||
|
||||
listOf<TextView>(
|
||||
bindingView.date,
|
||||
@ -941,7 +941,7 @@ class StandardWidget(val context: Context) {
|
||||
bindingView.weatherSubLineDivider,
|
||||
bindingView.weatherSubLineTemperature,
|
||||
).forEach {
|
||||
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
it.setShadowLayer(shadowRadius, shadowOffset, shadowOffset, shadowColor)
|
||||
}
|
||||
|
||||
// Icons shadow
|
||||
@ -955,7 +955,7 @@ class StandardWidget(val context: Context) {
|
||||
it.second.isVisible = it.first.isVisible
|
||||
it.second.scaleX = it.first.scaleX
|
||||
it.second.scaleY = it.first.scaleY
|
||||
it.second.applyShadow(it.first, 0.7f)
|
||||
it.second.applyShadow(it.first, 0.8f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -511,7 +511,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingBottom="32dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:duplicateParentState="true"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/colorSecondaryText"
|
||||
|
@ -16,7 +16,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="32dp"
|
||||
android:paddingBottom="48dp"
|
||||
android:orientation="vertical">
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
|
@ -76,7 +76,6 @@
|
||||
android:id="@+id/footer"
|
||||
android:padding="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:orientation="horizontal">
|
||||
<ImageView
|
||||
android:layout_width="48dp"
|
||||
|
@ -138,6 +138,8 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:gravity="center_vertical"
|
||||
android:id="@+id/sub_line"
|
||||
android:visibility="gone"
|
||||
@ -145,12 +147,12 @@
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:cropToPadding="false"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:cropToPadding="false"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:id="@+id/sub_line_icon_shadow"
|
||||
@ -158,7 +160,7 @@
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:cropToPadding="false"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:id="@+id/sub_line_icon"
|
||||
@ -179,6 +181,8 @@
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:layout_marginStart="2dp"
|
||||
|
@ -157,12 +157,16 @@
|
||||
android:layout_gravity="center"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:layoutDirection="locale"
|
||||
android:gravity="center">
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:gravity="center_vertical"
|
||||
android:id="@+id/sub_line"
|
||||
android:visibility="gone"
|
||||
@ -170,12 +174,12 @@
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:cropToPadding="false"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:cropToPadding="false"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:id="@+id/sub_line_icon_shadow"
|
||||
@ -183,7 +187,7 @@
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:cropToPadding="false"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:id="@+id/sub_line_icon"
|
||||
@ -203,6 +207,8 @@
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:layout_marginStart="2dp"
|
||||
|
@ -66,12 +66,12 @@
|
||||
<!-- Calendar -->
|
||||
<string name="settings_calendar_title">日历</string>
|
||||
<string name="title_permission_calendar">显示你的活动</string>
|
||||
<string name="description_permission_calendar">授予应用查看日历的权限以在微件中查看你的活动。</string>
|
||||
<string name="description_permission_calendar">授予访问日历的权限\n以在您的微件上查看活动。</string>
|
||||
<string name="settings_filter_calendar_title">过滤活动</string>
|
||||
<string name="settings_filter_calendar_subtitle">改变日历可见性</string>
|
||||
<string name="settings_all_day_title">全天活动</string>
|
||||
<string name="main_calendar">日历账户</string>
|
||||
<string name="calendar_settings_list_error">加载日历列表出现错误。</string>
|
||||
<string name="main_calendar">日历</string>
|
||||
<string name="calendar_settings_list_error">加载日历列表出错。</string>
|
||||
<string name="all_day">全天活动</string>
|
||||
<string name="show_events_visible">活动可见</string>
|
||||
<string name="show_events_not_visible">活动不可见</string>
|
||||
@ -100,7 +100,7 @@
|
||||
<string name="settings_show_multiple_events_title">多活动切换器</string>
|
||||
<string name="soon">即将</string>
|
||||
<string name="now">即刻</string>
|
||||
<string name="settings_widget_update_frequency_title">更新剩余时间的频率</string>
|
||||
<string name="settings_widget_update_frequency_title">剩余时间更新频率</string>
|
||||
<string name="settings_widget_update_frequency_subtitle">更新频率越高耗电量越大。</string>
|
||||
<string name="settings_widget_update_frequency_low">低</string>
|
||||
<string name="settings_widget_update_frequency_default">默认</string>
|
||||
@ -123,8 +123,8 @@
|
||||
|
||||
<!-- Weather -->
|
||||
<string name="settings_weather_title">天气</string>
|
||||
<string name="title_permission_location">显示天气信息</string>
|
||||
<string name="description_permission_location">授予位置权限\n以在您的微件上查看天气。</string>
|
||||
<string name="title_permission_location">显示天气</string>
|
||||
<string name="description_permission_location">授予定位权限\n以在您的微件上查看天气。</string>
|
||||
<string name="settings_unit_title">单位</string>
|
||||
<string name="fahrenheit" translatable="false">°F - 华氏度</string>
|
||||
<string name="celsius" translatable="false">°C - 摄氏度</string>
|
||||
@ -141,15 +141,15 @@
|
||||
<string name="show_weather_not_visible">天气信息不可见</string>
|
||||
<string name="settings_weather_app_title">天气</string>
|
||||
<string name="settings_weather_provider_api_key_title">天气API密钥</string>
|
||||
<string name="settings_weather_provider_api_key_subtitle_all_set">已正确配置天气信息来源。</string>
|
||||
<string name="settings_weather_provider_api_key_subtitle_not_set">必须配置天气信息来源。</string>
|
||||
<string name="settings_weather_provider_api_key_subtitle_all_set">已正确配置天气数据源。</string>
|
||||
<string name="settings_weather_provider_api_key_subtitle_not_set">必须配置天气数据源。</string>
|
||||
<string name="api_key_hint">OpenWeatherMap API密钥</string>
|
||||
<string name="default_weather_app">Google Weather</string>
|
||||
<string name="weather_warning">Google Awareness API已被弃用。要在微件上显示天气,您需要从第三方来源获取API密钥。</string>
|
||||
<string name="settings_weather_icon_pack_title">天气图标</string>
|
||||
<string name="default_weather_app">Google天气</string>
|
||||
<string name="weather_warning">Google Awareness API已被弃用。要在微件上显示天气,您需要从第三方数据源获取API密钥。</string>
|
||||
<string name="settings_weather_icon_pack_title">图标包</string>
|
||||
<string name="settings_weather_icon_pack_default">图标包%d</string>
|
||||
<string name="background_location_warning">选择地理定位后,即便应用未启动或在后台,我们也会收集您的定位数据来更新天气信息。\n这些数据不会用在其他地方。</string>
|
||||
<string name="settings_weather_provider_api">天气信息来源</string>
|
||||
<string name="settings_weather_provider_api">天气数据源</string>
|
||||
|
||||
<string name="settings_weather_provider_open_weather" translatable="false">OpenWeatherMap.org</string>
|
||||
<string name="settings_weather_provider_weatherbit" translatable="false">Weatherbit.io</string>
|
||||
@ -159,35 +159,35 @@
|
||||
<string name="settings_weather_provider_weather_gov" translatable="false">Weather.gov (USA)\nby National Weather Services</string>
|
||||
<string name="settings_weather_provider_yr" translatable="false">YR.no/Met.no\nby Meteorologisk Institutt</string>
|
||||
|
||||
<string name="weather_provider_info_open_weather_title">该天气信息来源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_weatherbit_title">该天气信息来源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_weatherapi_title">该天气信息来源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_here_title">该天气信息来源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_accuweather_title">该天气信息来源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_weather_gov_title">该天气信息来源仅在美国境内有效。</string>
|
||||
<string name="weather_provider_info_yr_title">该天气信息来源仅支持摄氏度单位。</string>
|
||||
<string name="weather_provider_info_open_weather_title">该天气数据源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_weatherbit_title">该天气数据源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_weatherapi_title">该天气数据源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_here_title">该天气数据源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_accuweather_title">该天气数据源需要API密钥才能正常工作。</string>
|
||||
<string name="weather_provider_info_weather_gov_title">该天气数据源仅对美国境内有效。</string>
|
||||
<string name="weather_provider_info_yr_title">该天气数据源仅支持摄氏度单位。</string>
|
||||
|
||||
<string name="weather_provider_info_open_weather_subtitle">前往天气信息来源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_weatherbit_subtitle">前往天气信息来源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_weatherapi_subtitle">前往天气信息来源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_here_subtitle">前往天气信息来源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_accuweather_subtitle">前往天气信息来源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_open_weather_subtitle">前往天气数据源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_weatherbit_subtitle">前往天气数据源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_weatherapi_subtitle">前往天气数据源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_here_subtitle">前往天气数据源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_accuweather_subtitle">前往天气数据源网站、创建个人账户并将默认密钥复制粘贴到此处。</string>
|
||||
<string name="weather_provider_info_weather_gov_subtitle">\n</string>
|
||||
<string name="weather_provider_info_yr_subtitle">\n</string>
|
||||
|
||||
<string name="weather_provider_error_missing_key">您选择的天气信息来源需要API密钥。</string>
|
||||
<string name="weather_provider_error_missing_key">您选择的天气数据源需要API密钥。</string>
|
||||
<string name="weather_provider_error_wrong_location">不支持当前位置。</string>
|
||||
<string name="weather_provider_error_missing_location">请选择一个有效的地址。</string>
|
||||
<string name="weather_provider_error_missing_location">请选择一个有效的位置。</string>
|
||||
<string name="weather_provider_error_expired_key">您的API密钥似乎已经过期了。</string>
|
||||
<string name="weather_provider_error_invalid_key">API密钥无效或尚未激活。</string>
|
||||
<string name="weather_provider_error_misconfigured">天气信息来源配置错误。</string>
|
||||
<string name="weather_provider_error_misconfigured">天气数据源配置错误。</string>
|
||||
<string name="weather_provider_error_connection">网络连接错误。</string>
|
||||
<string name="weather_provider_error_generic">出错了,请检查天气信息来源设置。</string>
|
||||
<string name="weather_provider_error_generic">出错了,请检查天气数据源设置。</string>
|
||||
<string name="api_key_required_message">需要账户</string>
|
||||
<string name="us_only_message">仅限美国</string>
|
||||
<string name="celsius_only_message">仅公制单位</string>
|
||||
<string name="weather_select_a_provider">选择信息来源</string>
|
||||
<string name="weather_provider_activity_subtitle">从列表中选择天气信息来源。\n部分来源需要注册免费个人账户,\n但它们通常也更精准。</string>
|
||||
<string name="weather_select_a_provider">选择数据源</string>
|
||||
<string name="weather_provider_activity_subtitle">从列表中选择天气数据源。\n部分数据源需要注册免费个人账户,\n但它们通常也更精准。</string>
|
||||
|
||||
<string name="location_access_notification_channel_id" translatable="false">location-access</string>
|
||||
<string name="location_access_notification_channel_name">天气更新服务</string>
|
||||
@ -241,8 +241,8 @@
|
||||
<string name="title_show_glance">显示速览信息</string>
|
||||
<string name="description_show_glance_visible">服务已启用</string>
|
||||
<string name="description_show_glance_not_visible">服务已禁用</string>
|
||||
<string name="settings_sort_glance_providers_title">来源优先级</string>
|
||||
<string name="settings_sort_glance_providers_subtitle">您可以通过拖放图标来调整下方列表的项目顺序,以此更改数据来源优先级。</string>
|
||||
<string name="settings_sort_glance_providers_title">数据源优先级</string>
|
||||
<string name="settings_sort_glance_providers_subtitle">您可以通过拖放图标来调整下方列表的项目顺序,以此更改数据源优先级。</string>
|
||||
<string name="settings_custom_notes_title">自定义提示</string>
|
||||
<string name="settings_daily_steps_title">运动健康</string>
|
||||
<string name="daily_steps_counter">目前走了%d步</string>
|
||||
@ -250,7 +250,7 @@
|
||||
<string name="battery_low_warning">电量低</string>
|
||||
<string name="charging">正在充电</string>
|
||||
<string name="charged">完全充满</string>
|
||||
<string name="providers">来源</string>
|
||||
<string name="providers">数据源</string>
|
||||
<string name="glance_info">仅在当前没有活动且满足特定条件时才会显示速览。</string>
|
||||
<string name="settings_music_players_filter_title">音乐播放器</string>
|
||||
<string name="settings_music_players_filter_subtitle">选择您常用的音乐播放器</string>
|
||||
@ -304,7 +304,7 @@
|
||||
</string-array>
|
||||
<string name="settings_show_events_as_glance_provider_title">活动</string>
|
||||
<string name="settings_show_events_as_glance_provider_subtitle">查看您的日历活动的速览,并始终显示当前日期。</string>
|
||||
<string name="settings_show_events_as_glance_provider_error">请在日历标签中启用活动显示,并授予所需的权限。</string>
|
||||
<string name="settings_show_events_as_glance_provider_error">请启用日历显示,并授予所需的权限。</string>
|
||||
<string name="events_glance_provider_format">%1$s %2$s</string>
|
||||
<string name="settings_show_weather_as_glance_provider_title">天气</string>
|
||||
<string name="settings_show_weather_as_glance_provider_subtitle">查看有关天气的更多信息,并始终显示当前日期。</string>
|
||||
@ -318,9 +318,9 @@
|
||||
<string name="action_about">关于</string>
|
||||
<string name="action_refresh_widget">刷新微件</string>
|
||||
<string name="toolbar_transition_name" translatable="false">toolbar</string>
|
||||
<string name="error_opening_uri">打开URL时遭遇出错:链接已复制到剪贴板。</string>
|
||||
<string name="error_opening_uri">打开URL出错:链接已复制到剪贴板。</string>
|
||||
<string name="loading_text">正在加载数据……</string>
|
||||
<string name="error_opening_app">打开应用时出错。</string>
|
||||
<string name="error_opening_app">打开应用出错。</string>
|
||||
<string name="default_name">默认应用</string>
|
||||
<string name="action_save">保存</string>
|
||||
<string name="settings_visible">可见</string>
|
||||
@ -344,17 +344,17 @@
|
||||
<string name="settings_feedback_subtitle">欢迎为该项目贡献您的力量!</string>
|
||||
<string name="settings_feedback_title">反馈和功能请求</string>
|
||||
<string name="xiaomi_manufacturer" translatable="false">xiaomi</string>
|
||||
<string name="xiaomi_warning_title">检测到小米设备</string>
|
||||
<string name="xiaomi_warning_message">请在应用设置的「其他权限」中授予允许程序在后台运行时显示弹出窗口的权限,否则您将无法通过点击微件打开任何应用。</string>
|
||||
<string name="xiaomi_warning_title">小米设备</string>
|
||||
<string name="xiaomi_warning_message">请在应用设置的其他权限部分授予后台弹出界面的权限,否则您将无法通过点击微件打开任何应用。</string>
|
||||
<string name="action_ignore">忽略</string>
|
||||
<string name="action_grant_permission">授予权限</string>
|
||||
<string name="settings_title">设置</string>
|
||||
<string name="style_header">风格</string>
|
||||
<string name="actions_header">动作</string>
|
||||
<string name="provider_header">来源</string>
|
||||
<string name="provider_header">数据源</string>
|
||||
<string name="appearance_header">外观</string>
|
||||
<string name="preferences_header">偏好</string>
|
||||
<string name="settings_privacy_policy_title"><![CDATA[法务与隐私]]></string>
|
||||
<string name="settings_privacy_policy_title">法务与隐私</string>
|
||||
<string name="settings_privacy_policy_subtitle">查看应用的隐私策略</string>
|
||||
<string name="project_header">开源项目</string>
|
||||
<string name="information_header">信息</string>
|
||||
@ -369,8 +369,8 @@
|
||||
<string name="donation_breakfast">一顿英式早餐</string>
|
||||
<string name="donation_lunch">一顿快餐</string>
|
||||
<string name="action_show_widget_preview">显示微件预览</string>
|
||||
<string name="support_dev_subtitle">这是一个独立开发者的项目,谢谢您的支持!</string>
|
||||
<string name="settings_title_integrations">整合</string>
|
||||
<string name="support_dev_subtitle">这是一个独立开发者的项目,\n谢谢您的支持!</string>
|
||||
<string name="settings_title_integrations">集成</string>
|
||||
<string name="label_count_installed_integrations">已安装%d个集成插件</string>
|
||||
<string name="nothing">无</string>
|
||||
<string name="action_dismiss">拒绝</string>
|
||||
@ -380,13 +380,13 @@
|
||||
<string name="song_info_format_activity_subtitle">更改曲目的可见信息</string>
|
||||
|
||||
<!-- More -->
|
||||
<string name="look_and_feel_header"><![CDATA[外观与视觉]]></string>
|
||||
<string name="look_and_feel_header">界面外观</string>
|
||||
<string name="typography_settings_title">文本</string>
|
||||
<string name="typography_settings_subtitle">设置文本字体、大小和颜色</string>
|
||||
<string name="layout_settings_title">布局</string>
|
||||
<string name="gestures_settings_subtitle">动作、行为与快捷方式</string>
|
||||
<string name="gestures_settings_title">交互</string>
|
||||
<string name="gestures_amp_input_header"><![CDATA[操作与交互]]></string>
|
||||
<string name="gestures_settings_title">手势</string>
|
||||
<string name="gestures_amp_input_header">手势与输入</string>
|
||||
<string name="clock_settings_subtitle">设置大小、颜色与时区</string>
|
||||
<string name="layout_settings_subtitle">微件间距及其它微调</string>
|
||||
<string name="smart_content_header">智能内容</string>
|
||||
|
@ -7,7 +7,6 @@ buildscript {
|
||||
jcenter()
|
||||
maven { url 'https://jitpack.io' }
|
||||
mavenCentral()
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.0'
|
||||
@ -17,8 +16,6 @@ buildscript {
|
||||
// Add the Crashlytics Gradle plugin.
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.2'
|
||||
|
||||
classpath 'io.realm:realm-gradle-plugin:10.4.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
@ -30,7 +27,6 @@ allprojects {
|
||||
jcenter()
|
||||
maven { url 'https://jitpack.io' }
|
||||
mavenCentral()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user