Skip to content

Commit db06cfd

Browse files
author
ELY M
committed
55904-elys
1 parent a0d7835 commit db06cfd

6 files changed

Lines changed: 163 additions & 44 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2424
xmlns:tools="http://schemas.android.com/tools"
25-
android:versionCode="55903"
26-
android:versionName="55903-elys">
25+
android:versionCode="55904"
26+
android:versionName="55904-elys">
2727

2828
<uses-permission android:name="android.permission.INTERNET" />
2929
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@@ -77,7 +77,7 @@
7777
android:usesCleartextTraffic="true">
7878

7979
<activity
80-
android:name=".StartupActivity"
80+
android:name="elys.joshuatee.wx.StartupActivity"
8181
android:requestLegacyExternalStorage="true"
8282
android:launchMode="singleTop"
8383
android:exported="true">
@@ -91,7 +91,7 @@
9191
android:resource="@xml/shortcuts" />
9292
</activity>
9393
<activity
94-
android:name=".WX"
94+
android:name="elys.joshuatee.wx.WX"
9595
android:launchMode="singleTop"
9696
android:theme="@style/MyCustomTheme_whiter_NOAB" />
9797
<activity
@@ -271,7 +271,7 @@
271271
android:parentActivityName="WX" />
272272

273273
<receiver
274-
android:name=".Widget"
274+
android:name="elys.joshuatee.wx.Widget"
275275
android:exported="true">
276276
<intent-filter>
277277
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -282,7 +282,7 @@
282282
</receiver>
283283

284284
<receiver
285-
android:name=".WidgetCC"
285+
android:name="elys.joshuatee.wx.WidgetCC"
286286
android:exported="true">
287287
<intent-filter>
288288
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -294,7 +294,7 @@
294294

295295

296296
<receiver
297-
android:name=".WidgetNexrad"
297+
android:name="elys.joshuatee.wx.WidgetNexrad"
298298
android:exported="true">
299299
<intent-filter>
300300
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -305,7 +305,7 @@
305305
</receiver>
306306

307307
<receiver
308-
android:name=".WidgetMosaics"
308+
android:name="elys.joshuatee.wx.WidgetMosaics"
309309
android:exported="true">
310310
<intent-filter>
311311
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -316,7 +316,7 @@
316316
</receiver>
317317

318318
<receiver
319-
android:name=".WidgetMosaicsRad"
319+
android:name="elys.joshuatee.wx.WidgetMosaicsRad"
320320
android:exported="true">
321321
<intent-filter>
322322
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -327,7 +327,7 @@
327327
</receiver>
328328

329329
<receiver
330-
android:name=".WidgetTextProd"
330+
android:name="elys.joshuatee.wx.WidgetTextProd"
331331
android:exported="true">
332332
<intent-filter>
333333
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -338,7 +338,7 @@
338338
</receiver>
339339

340340
<receiver
341-
android:name=".WidgetTextHWO"
341+
android:name="elys.joshuatee.wx.WidgetTextHWO"
342342
android:exported="true">
343343
<intent-filter>
344344
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -349,7 +349,7 @@
349349
</receiver>
350350

351351
<receiver
352-
android:name=".WidgetSPCMESO"
352+
android:name="elys.joshuatee.wx.WidgetSPCMESO"
353353
android:exported="true">
354354
<intent-filter>
355355
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -360,7 +360,7 @@
360360
</receiver>
361361

362362
<receiver
363-
android:name=".WidgetSPCSWO"
363+
android:name="elys.joshuatee.wx.WidgetSPCSWO"
364364
android:exported="true">
365365
<intent-filter>
366366
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -371,7 +371,7 @@
371371
</receiver>
372372

373373
<receiver
374-
android:name=".WidgetWPCIMG"
374+
android:name="elys.joshuatee.wx.WidgetWPCIMG"
375375
android:exported="true">
376376
<intent-filter>
377377
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -382,7 +382,7 @@
382382
</receiver>
383383

384384
<receiver
385-
android:name=".WidgetCONUSWV"
385+
android:name="elys.joshuatee.wx.WidgetCONUSWV"
386386
android:exported="true">
387387
<intent-filter>
388388
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -393,7 +393,7 @@
393393
</receiver>
394394

395395
<receiver
396-
android:name=".WidgetSTRPT"
396+
android:name="elys.joshuatee.wx.WidgetSTRPT"
397397
android:exported="true">
398398
<intent-filter>
399399
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -404,7 +404,7 @@
404404
</receiver>
405405

406406
<receiver
407-
android:name=".WidgetNHC"
407+
android:name="elys.joshuatee.wx.WidgetNHC"
408408
android:exported="true">
409409
<intent-filter>
410410
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -415,7 +415,7 @@
415415
</receiver>
416416

417417
<receiver
418-
android:name=".WidgetTextWPC"
418+
android:name="elys.joshuatee.wx.WidgetTextWPC"
419419
android:exported="true">
420420
<intent-filter>
421421
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -500,7 +500,7 @@
500500

501501
<provider
502502
android:name=".util.FileProvider"
503-
android:authorities=".fileprovider"
503+
android:authorities="elys.joshuatee.wx.fileprovider"
504504
android:exported="false"
505505
android:grantUriPermissions="true">
506506
<meta-data
@@ -532,11 +532,11 @@
532532
<provider
533533
android:name="WeatherDataProvider"
534534
android:exported="true"
535-
android:authorities=".weatherlistwidget.provider"
535+
android:authorities="elys.joshuatee.wx.weatherlistwidget.provider"
536536
tools:ignore="ExportedContentProvider" />
537537

538538
<service
539-
android:name=".notifications.WXJobService"
539+
android:name="elys.joshuatee.wx.notifications.WXJobService"
540540
android:permission="android.permission.BIND_JOB_SERVICE"
541541
android:exported="true" />
542542

app/src/main/java/joshuatee/wx/MyApplication.kt

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import joshuatee.wx.settings.NotificationPreferences
4242
import joshuatee.wx.settings.RadarPreferences
4343
import joshuatee.wx.settings.UIPreferences
4444
import joshuatee.wx.settings.UtilityHomeScreen
45+
import joshuatee.wx.util.HttpUnsafe
4546
import okhttp3.Interceptor
4647
import okhttp3.OkHttpClient
4748
import org.acra.BuildConfig
@@ -102,13 +103,26 @@ class MyApplication : Application() {
102103
val res = resources
103104
dm = res.displayMetrics
104105
UIPreferences.deviceScale = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, dm)
105-
UIPreferences.padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, res.getDimension(R.dimen.padding_dynamic_tv), dm).toInt()
106-
UIPreferences.paddingSettings = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, res.getDimension(R.dimen.padding_dynamic_tv_settings), dm).toInt()
107-
UIPreferences.paddingSmall = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, res.getDimension(R.dimen.padding_dynamic_tv_small), dm).toInt()
106+
UIPreferences.padding = TypedValue.applyDimension(
107+
TypedValue.COMPLEX_UNIT_DIP,
108+
res.getDimension(R.dimen.padding_dynamic_tv),
109+
dm
110+
).toInt()
111+
UIPreferences.paddingSettings = TypedValue.applyDimension(
112+
TypedValue.COMPLEX_UNIT_DIP,
113+
res.getDimension(R.dimen.padding_dynamic_tv_settings),
114+
dm
115+
).toInt()
116+
UIPreferences.paddingSmall = TypedValue.applyDimension(
117+
TypedValue.COMPLEX_UNIT_DIP,
118+
res.getDimension(R.dimen.padding_dynamic_tv_small),
119+
dm
120+
).toInt()
108121
UIPreferences.lLpadding = res.getDimension(R.dimen.padding_ll)
109122
val tv = TypedValue()
110123
if (theme.resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
111-
UIPreferences.actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, res.displayMetrics)
124+
UIPreferences.actionBarHeight =
125+
TypedValue.complexToDimensionPixelSize(tv.data, res.displayMetrics)
112126
}
113127
initPreferences(this)
114128
Location.refreshLocationData(this)
@@ -130,10 +144,12 @@ class MyApplication : Application() {
130144
response
131145
}
132146
val httpClient = OkHttpClient.Builder()
133-
.connectTimeout(15, TimeUnit.SECONDS)
134-
.readTimeout(15, TimeUnit.SECONDS)
135-
.addInterceptor(okHttp3Interceptor)
136-
.build()
147+
.connectTimeout(15, TimeUnit.SECONDS)
148+
.readTimeout(15, TimeUnit.SECONDS)
149+
.addInterceptor(okHttp3Interceptor)
150+
.build()
151+
152+
val httpClientUnsafe = HttpUnsafe.getUnsafeOkHttpClient()
137153

138154
lateinit var preferences: SharedPreferences
139155
private lateinit var preferencesTelecine: SharedPreferences
@@ -149,13 +165,22 @@ class MyApplication : Application() {
149165
RadarPreferences.radarGeometrySetColors()
150166
NotificationPreferences.initPreferences()
151167
NexradUtil.colorPaletteProducts.forEach {
152-
ColorPalette.radarColorPalette[it] = getInitialPreferenceString("RADAR_COLOR_PALETTE_$it", "CODENH")
153-
ColorPalette.radarColorPaletteList[it] = getInitialPreferenceString("RADAR_COLOR_PALETTE_" + it + "_LIST", "")
168+
ColorPalette.radarColorPalette[it] =
169+
getInitialPreferenceString("RADAR_COLOR_PALETTE_$it", "CODENH")
170+
ColorPalette.radarColorPaletteList[it] =
171+
getInitialPreferenceString("RADAR_COLOR_PALETTE_" + it + "_LIST", "")
154172
}
155-
UIPreferences.cardCorners = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, preferences.getInt("CARD_CORNER_RADIUS", 0).toFloat(), dm)
156-
UIPreferences.telecineVideoSizePercentage = preferencesTelecine.getInt("video-size", 100)
157-
UIPreferences.telecineSwitchShowCountdown = preferencesTelecine.getBoolean("show-countdown", false)
158-
UIPreferences.telecineSwitchRecordingNotification = preferencesTelecine.getBoolean("recording-notification", false)
173+
UIPreferences.cardCorners = TypedValue.applyDimension(
174+
TypedValue.COMPLEX_UNIT_DIP,
175+
preferences.getInt("CARD_CORNER_RADIUS", 0).toFloat(),
176+
dm
177+
)
178+
UIPreferences.telecineVideoSizePercentage =
179+
preferencesTelecine.getInt("video-size", 100)
180+
UIPreferences.telecineSwitchShowCountdown =
181+
preferencesTelecine.getBoolean("show-countdown", false)
182+
UIPreferences.telecineSwitchRecordingNotification =
183+
preferencesTelecine.getBoolean("recording-notification", false)
159184
Location.currentLocationStr = getInitialPreferenceString("CURRENT_LOC_FRAGMENT", "1")
160185
PolygonWatch.load(context)
161186
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package joshuatee.wx.util
2+
3+
import okhttp3.Interceptor
4+
import okhttp3.OkHttpClient
5+
import java.security.SecureRandom
6+
import java.security.cert.X509Certificate
7+
import java.util.concurrent.TimeUnit
8+
import javax.net.ssl.HostnameVerifier
9+
import javax.net.ssl.SSLContext
10+
import javax.net.ssl.SSLSocketFactory
11+
import javax.net.ssl.TrustManager
12+
import javax.net.ssl.X509TrustManager
13+
import javax.security.cert.CertificateException
14+
15+
//
16+
// create an OkHttpClient that does not check SSL certs
17+
// On 2024-08-23 connections to TGFTP broke likely due to an incomplete cert renewal
18+
// since radar data is not sensitive data this temporary workaround is fine
19+
//
20+
21+
object HttpUnsafe {
22+
23+
fun getUnsafeOkHttpClient(): OkHttpClient {
24+
try {
25+
// Create a trust manager that does not validate certificate chains
26+
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
27+
@Throws(CertificateException::class)
28+
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
29+
}
30+
31+
@Throws(CertificateException::class)
32+
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
33+
}
34+
35+
override fun getAcceptedIssuers(): Array<X509Certificate> {
36+
return arrayOf()
37+
}
38+
}
39+
)
40+
41+
// Install the all-trusting trust manager
42+
val sslContext = SSLContext.getInstance("SSL")
43+
sslContext.init(null, trustAllCerts, SecureRandom())
44+
// Create an ssl socket factory with our all-trusting manager
45+
val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
46+
47+
val okHttp3Interceptor = Interceptor { chain ->
48+
val request = chain.request()
49+
var response = chain.proceed(request)
50+
var tryCount = 0
51+
while (!response.isSuccessful && tryCount < 3) {
52+
tryCount += 1
53+
response.close()
54+
response = chain.proceed(request)
55+
}
56+
response
57+
}
58+
59+
val builder = OkHttpClient.Builder()
60+
builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
61+
builder.hostnameVerifier(HostnameVerifier { hostname, session -> true })
62+
builder.connectTimeout(15, TimeUnit.SECONDS)
63+
builder.readTimeout(15, TimeUnit.SECONDS)
64+
builder.addInterceptor(okHttp3Interceptor)
65+
66+
val okHttpClient: OkHttpClient = builder.build()
67+
return okHttpClient
68+
} catch (e: Exception) {
69+
throw RuntimeException(e)
70+
}
71+
}
72+
}

app/src/main/java/joshuatee/wx/util/UtilityNetworkIO.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ object UtilityNetworkIO {
3838
UtilityLog.download("getStringFromUrlNew $withNewLine: $url")
3939
val out = StringBuilder(5000)
4040
try {
41-
val request = Request.Builder().url(url).header("User-Agent", GlobalVariables.HTTP_USER_AGENT).build()
42-
val response = MyApplication.httpClient.newCall(request).execute()
41+
val request =
42+
Request.Builder().url(url).header("User-Agent", GlobalVariables.HTTP_USER_AGENT)
43+
.build()
44+
// val response = MyApplication.httpClient.newCall(request).execute()
45+
val response = MyApplication.httpClientUnsafe.newCall(request).execute()
4346
val inputStream = BufferedInputStream(response.body.byteStream())
4447
val bufferedReader = BufferedReader(InputStreamReader(inputStream))
4548
var line: String? = bufferedReader.readLine()
@@ -70,12 +73,17 @@ object UtilityNetworkIO {
7073
// String.getImage()
7174
fun getBitmapFromUrl(url: String): Bitmap = try {
7275
UtilityLog.download("getBitmapFromUrl: $url")
73-
val request = Request.Builder().url(url).header("User-Agent", GlobalVariables.HTTP_USER_AGENT).build()
76+
val request =
77+
Request.Builder().url(url).header("User-Agent", GlobalVariables.HTTP_USER_AGENT).build()
7478
val response = MyApplication.httpClient.newCall(request).execute()
7579
if (url.contains("hazards_d8_14_contours.png")) {
7680
val options = BitmapFactory.Options()
7781
options.inPreferredConfig = Bitmap.Config.RGB_565
78-
BitmapFactory.decodeStream(BufferedInputStream(response.body.byteStream()), null, options)!!
82+
BitmapFactory.decodeStream(
83+
BufferedInputStream(response.body.byteStream()),
84+
null,
85+
options
86+
)!!
7987
} else {
8088
BitmapFactory.decodeStream(BufferedInputStream(response.body.byteStream()))
8189
}
@@ -89,8 +97,10 @@ object UtilityNetworkIO {
8997
// raw downloads - nexrad radar files, etc
9098
fun getInputStreamFromUrl(url: String): InputStream? = try {
9199
UtilityLog.download("getInputStreamFromUrl: $url")
92-
val request = Request.Builder().url(url).header("User-Agent", GlobalVariables.HTTP_USER_AGENT).build()
93-
val response = MyApplication.httpClient.newCall(request).execute()
100+
val request =
101+
Request.Builder().url(url).header("User-Agent", GlobalVariables.HTTP_USER_AGENT).build()
102+
// val response = MyApplication.httpClient.newCall(request).execute()
103+
val response = MyApplication.httpClientUnsafe.newCall(request).execute()
94104
response.body.byteStream()
95105
} catch (e: IOException) {
96106
UtilityLog.handleException(e)

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ buildscript {
88
}
99

1010
dependencies {
11-
classpath 'com.android.tools.build:gradle:8.5.1'
11+
classpath 'com.android.tools.build:gradle:8.5.2'
1212
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-gradle-plugin
1313
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23"
1414
}

0 commit comments

Comments
 (0)