Add a content provider

This commit is contained in:
Julien Papasian 2025-08-06 21:37:18 +02:00 committed by Julien Papasian
parent 526cee5f96
commit 242430a269
15 changed files with 1103 additions and 1 deletions

View file

@ -1,5 +1,8 @@
# Version 6.0.5-alpha (not yet released)
**New features**
- Content provider: allows (with your permission) other apps to query your weather data. [Read the announcement](https://github.com/breezy-weather/breezy-weather/discussions/2089)
**Removed features**
- Mean daytime/nighttime temperatures as threshold lines. Use a normals source instead

View file

@ -8,4 +8,6 @@ The icon packs feature (which allows you to customize weather icons) requires to
Breezy Weather relies on third-party APIs to get various data such as your current location (if you decide to not use native GPS), location search or weather, please review their privacy policy (from Settings > Info icon > Privacy policy) and only use the ones you agree with.
This privacy policy may be updated any time, for example to clarify a use case or in case a feature gets added. In that case, it will be mentioned in the changelog. You can always access the latest version of the privacy policy from Settings > Info icon > Privacy policy.
Breezy Weather can optionally share your location and weather data with other apps. Please review their privacy policy before you decide to grant them permission.
This privacy policy may be updated any time, for example to clarify a use case or in case a feature gets added. In that case, it will be mentioned in the changelog. You can always access the latest version of the privacy policy from Settings > Info icon > Privacy policy.

View file

@ -271,6 +271,7 @@ dependencies {
implementation(projects.domain)
implementation(projects.mapsUtils)
implementation(projects.uiWeatherView)
implementation(libs.breezy.datasharing.lib)
implementation(libs.core.ktx)
implementation(libs.appcompat)

View file

@ -41,6 +41,14 @@
<!-- weather update in background -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<!-- Data sharing -->
<permission
android:description="@string/content_provider_permission_description"
android:icon="@drawable/ic_launcher_foreground"
android:label="@string/content_provider_permission_label"
android:name="${applicationId}.READ_PROVIDER"
android:protectionLevel="dangerous" />
<uses-feature
android:name="android.software.live_wallpaper"
android:required="false" />
@ -526,6 +534,12 @@
android:foregroundServiceType="dataSync|shortService"
tools:node="merge" />
<provider
android:name=".background.provider.WeatherContentProvider"
android:authorities="${applicationId}.provider.weather"
android:exported="true"
android:readPermission="${applicationId}.READ_PROVIDER" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"

File diff suppressed because it is too large Load diff

View file

@ -138,6 +138,10 @@ enum class DistanceUnit(
fun validateValue(distance: Double?): Double? {
return distance?.let { if (it >= 0.0) it else null }
}
fun getUnit(id: String): DistanceUnit? {
return DistanceUnit.entries.firstOrNull { it.id == id }
}
}
override val valueArrayId = R.array.distance_unit_values

View file

@ -98,6 +98,10 @@ enum class PrecipitationUnit(
fun validateValue(precipitation: Double?): Double? {
return precipitation?.let { if (it in 0.0..10000.0) it else null }
}
fun getUnit(id: String): PrecipitationUnit? {
return PrecipitationUnit.entries.firstOrNull { it.id == id }
}
}
override val valueArrayId = R.array.precipitation_unit_values
@ -219,6 +223,10 @@ enum class PrecipitationIntensityUnit(
precipitationIntensity = validateValue(minutely.precipitationIntensity)
)
}
fun getUnit(id: String): PrecipitationIntensityUnit? {
return PrecipitationIntensityUnit.entries.firstOrNull { it.id == id }
}
}
override val valueArrayId = R.array.precipitation_intensity_unit_values

View file

@ -110,6 +110,10 @@ enum class PressureUnit(
fun validateValue(pressure: Double?): Double? {
return pressure?.let { if (it in 800.0..1200.0) it else null }
}
fun getUnit(id: String): PressureUnit? {
return PressureUnit.entries.firstOrNull { it.id == id }
}
}
override val valueArrayId = R.array.pressure_unit_values

View file

@ -169,6 +169,10 @@ enum class SpeedUnit(
gusts = SpeedUnit.validateValue(wind.gusts)
)
}
fun getUnit(id: String): SpeedUnit? {
return SpeedUnit.entries.firstOrNull { it.id == id }
}
}
override val valueArrayId = R.array.speed_unit_values

View file

@ -85,6 +85,10 @@ enum class TemperatureUnit(
fun validateValue(temperature: Double?): Double? {
return temperature?.let { if (it in -100.0..100.0) it else null }
}
fun getUnit(id: String): TemperatureUnit? {
return TemperatureUnit.entries.firstOrNull { it.id == id }
}
}
override val valueArrayId = R.array.temperature_unit_values

View file

@ -21,6 +21,18 @@ import androidx.annotation.ColorInt
import breezyweather.domain.weather.model.AirQuality
import org.breezyweather.domain.weather.index.PollutantIndex
val AirQuality.validPollutants: List<PollutantIndex>
get() {
return listOf(
PollutantIndex.NO2,
PollutantIndex.O3,
PollutantIndex.PM10,
PollutantIndex.PM25,
PollutantIndex.SO2,
PollutantIndex.CO
).filter { getConcentration(it) != null }
}
fun AirQuality.getIndex(pollutant: PollutantIndex? = null): Int? {
return if (pollutant == null) { // Air Quality
val pollutantsAqi: List<Int> = listOfNotNull(

View file

@ -826,6 +826,11 @@
<string name="unit_mum_voice">Micromètres</string>
<string name="notification_channel_alerts">Vigilances</string>
<string name="about_matrix">Salon Matrix</string>
<!-- Content provider -->
<string name="content_provider_permission_label">Lire les données de Breezy Weather</string>
<string name="content_provider_permission_description">obtenir les informations météo de Breezy Weather, y compris les coordonnées de vos emplacements, tels que votre emplacement actuel si vous lavez ajouté</string>
<string name="null_data_text">N/A</string>
<string name="colon_separator">\u0020:\u0020</string>
<string name="notification_update_error">%d mise(s) à jour en échec</string>

View file

@ -977,6 +977,9 @@
<string name="about_contribution_designer">Logo designer</string>
<!-- %s is a link -->
<string name="about_open_link_message">Open %s?</string>
<!-- Content provider -->
<string name="content_provider_permission_label">Read Breezy Weather data</string>
<string name="content_provider_permission_description">get weather information from Breezy Weather, including the coordinates of your locations, such as your current location if you added it</string>
<!-- Weather condition text -->
<!-- Check https://unterm.un.org/unterm2/en/ -->
<!-- We dont use all of them currently, but they might come useful some day -->

View file

@ -5,6 +5,7 @@ activity = "1.10.1"
adaptiveiconview = "v0.0.3"
agp = "8.12.0"
appcompat = "1.7.1"
breezy-datasharing-lib = "f8de782425422a896fc8e01b6e925cef9ed5c306"
cardview = "1.0.0"
compose-bom = "2025.07.00"
compose-material3 = "1.5.0-alpha01"
@ -57,6 +58,7 @@ accompanist-permissions = { group = "com.google.accompanist", name = "accompanis
adaptiveiconview = { group = "com.github.breezy-weather", name = "AdaptiveIconView", version.ref = "adaptiveiconview" }
android-gradle = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
breezy-datasharing-lib = { group = "com.github.breezy-weather", name = "breezy-weather-data-sharing-lib", version.ref = "breezy-datasharing-lib" }
cardview = { group = "androidx.cardview", name = "cardview", version.ref = "cardview" }
compose-animation = { group = "androidx.compose.animation", name = "animation" }
compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }

View file

@ -35,3 +35,11 @@ include(":data")
include(":domain")
include(":maps-utils")
include(":ui-weather-view")
// To test local changes
/*includeBuild("../breezy-weather-data-sharing-lib/") {
dependencySubstitution {
substitute(module("com.github.breezy-weather:breezy-weather-data-sharing-lib"))
.using(project(":lib"))
}
}*/