@@ -497,6 +497,116 @@ fun sortMessages(messages: List<Message>): List<Message> {
497497 )
498498}
499499
500+ fun Context.openFirstWeatherApp () {
501+ val pm = this .packageManager
502+ AppLogger .d(" WeatherAppLauncher" , " Starting search for weather apps..." )
503+
504+ // --- Option 1: Known weather apps ---
505+ val knownWeatherPackages = listOf (
506+ " com.accuweather.android" , // AccuWeather
507+ " com.weather.Weather" , // The Weather Channel
508+ " com.windyty.android" , // Windy.com
509+ " co.windyapp.android" , // Windy.app
510+ " com.aws.android" , // WeatherBug
511+ " com.wunderground.android.weather" , // Weather Underground
512+ " com.handmark.expressweather" , // 1Weather
513+ " net.darksky.darksky" , // Dark Sky (if still installed)
514+ " com.luckycatlabs.sunrisesunset" , // (example: some weather apps embed this)
515+ " de.mdiener.rain.usa" , // Rain Alarm (example)
516+ " com.noaa.weather" , // Hypothetical NOAA-based app
517+ " com.yahoo.mobile.client.android.weather" , // Yahoo Weather
518+ " org.breezyweather" // Breezy Weather
519+ )
520+
521+ val installedKnownApps = knownWeatherPackages.filter {
522+ try {
523+ pm.getPackageInfo(it, 0 )
524+ AppLogger .d(" WeatherAppLauncher" , " Found known weather app: $it " )
525+ true
526+ } catch (_: PackageManager .NameNotFoundException ) {
527+ false
528+ }
529+ }
530+
531+ if (installedKnownApps.isNotEmpty()) {
532+ val intent = pm.getLaunchIntentForPackage(installedKnownApps.first())
533+ if (intent != null ) {
534+ AppLogger .d(" WeatherAppLauncher" , " Launching known weather app: ${installedKnownApps.first()} " )
535+ this .startActivity(intent)
536+ return
537+ } else {
538+ AppLogger .d(" WeatherAppLauncher" , " Launch intent null for: ${installedKnownApps.first()} " )
539+ }
540+ } else {
541+ AppLogger .d(" WeatherAppLauncher" , " No known weather apps installed." )
542+ }
543+
544+ // --- Option 2: Try generic weather intent (rarely works) ---
545+ val genericIntent = Intent (Intent .ACTION_VIEW , " weather://" .toUri())
546+ val resolvedApps = pm.queryIntentActivities(genericIntent, PackageManager .MATCH_DEFAULT_ONLY )
547+ if (resolvedApps.isNotEmpty()) {
548+ val packageName = resolvedApps.first().activityInfo.packageName
549+ val intent = pm.getLaunchIntentForPackage(packageName)
550+ if (intent != null ) {
551+ AppLogger .d(" WeatherAppLauncher" , " Launching app via generic weather intent: $packageName " )
552+ this .startActivity(intent)
553+ return
554+ } else {
555+ AppLogger .d(" WeatherAppLauncher" , " Launch intent null for generic weather app: $packageName " )
556+ }
557+ } else {
558+ AppLogger .d(" WeatherAppLauncher" , " No apps found via generic weather intent." )
559+ }
560+
561+ // --- Option 3: Scan all installed apps for "weather" in name ---
562+ val weatherAppsByName = pm.getInstalledApplications(PackageManager .GET_META_DATA )
563+ .filter { app ->
564+ val name = pm.getApplicationLabel(app).toString().lowercase()
565+ val containsWeather = name.contains(" weather" )
566+ if (containsWeather) AppLogger .d(" WeatherAppLauncher" , " Found app by name: ${app.packageName} ($name )" )
567+ containsWeather
568+ }
569+
570+ if (weatherAppsByName.isNotEmpty()) {
571+ val intent = pm.getLaunchIntentForPackage(weatherAppsByName.first().packageName)
572+ if (intent != null ) {
573+ AppLogger .d(" WeatherAppLauncher" , " Launching first app found by name: ${weatherAppsByName.first().packageName} " )
574+ this .startActivity(intent)
575+ return
576+ } else {
577+ AppLogger .d(" WeatherAppLauncher" , " Launch intent null for: ${weatherAppsByName.first().packageName} " )
578+ }
579+ } else {
580+ AppLogger .d(" WeatherAppLauncher" , " No apps found by name containing 'weather'." )
581+ }
582+
583+ val prefs = Prefs (this )
584+
585+ // --- Fallback if no weather app is found ---
586+ val coords = prefs.loadLocation()
587+ if (coords != null ) {
588+ val (lat, lon) = coords
589+
590+ // Use prefs.tempUnit to determine unit parameter for weather.com
591+ val unitParam = when (prefs.tempUnit) {
592+ Constants .TempUnits .Celsius -> " c" // Metric
593+ Constants .TempUnits .Fahrenheit -> " f" // Fahrenheit
594+ }
595+
596+ // Construct the URL with lat/lon and unit
597+ val url = " https://weather.com/weather/today/l/$lat ,$lon ?unit=$unitParam "
598+
599+ // Open in browser
600+ val intent = Intent (Intent .ACTION_VIEW , url.toUri())
601+ this .startActivity(intent)
602+
603+ AppLogger .d(" WeatherAppLauncher" , " Opened weather.com for coordinates: $lat ,$lon with unit: $unitParam " )
604+ } else {
605+ AppLogger .d(" WeatherAppLauncher" , " No coordinates found in prefs." )
606+ }
607+
608+ }
609+
500610
501611fun formatLongToCalendar (longTimestamp : Long ): String {
502612 // Create a Calendar instance and set its time to the given timestamp (in milliseconds)
0 commit comments