Replace app icon with Joykoo brand logo and improve WebView error handling
Some checks failed
APK-BUILD/pipeline/head There was a failure building this commit

Use the Jk logo from smart.joykoo.mx as the launcher icon (legacy PNGs
and adaptive icon foreground at all densities). Add SSL/HTTP error
handling so failures show the error overlay instead of a silent white
screen. Add JS console logging to logcat and WebView debugging for
debug builds. Relax mixed content mode to compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
caspar 2026-10-08 00:13:20 -04:00
parent f99c6c05fa
commit e6ac00fe2a
15 changed files with 37 additions and 65 deletions

View File

@ -9,16 +9,20 @@ import android.net.NetworkCapabilities
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.WindowInsets import android.view.WindowInsets
import android.view.WindowInsetsController import android.view.WindowInsetsController
import android.view.WindowManager import android.view.WindowManager
import android.webkit.ConsoleMessage
import android.webkit.CookieManager import android.webkit.CookieManager
import android.webkit.SslErrorHandler
import android.webkit.ValueCallback import android.webkit.ValueCallback
import android.webkit.WebChromeClient import android.webkit.WebChromeClient
import android.webkit.WebResourceError import android.webkit.WebResourceError
import android.webkit.WebResourceRequest import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebSettings import android.webkit.WebSettings
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
@ -98,9 +102,7 @@ class MainActivity : AppCompatActivity() {
domStorageEnabled = true domStorageEnabled = true
databaseEnabled = true databaseEnabled = true
// Allow mixed content only if absolutely necessary for the target site. mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE
// Default to the safest option.
mixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW
// Cache and storage for session persistence // Cache and storage for session persistence
cacheMode = WebSettings.LOAD_DEFAULT cacheMode = WebSettings.LOAD_DEFAULT
@ -129,6 +131,8 @@ class MainActivity : AppCompatActivity() {
setAcceptThirdPartyCookies(webView, true) setAcceptThirdPartyCookies(webView, true)
} }
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG)
webView.webViewClient = ScannerWebViewClient() webView.webViewClient = ScannerWebViewClient()
webView.webChromeClient = ScannerWebChromeClient() webView.webChromeClient = ScannerWebChromeClient()
} }
@ -315,21 +319,44 @@ class MainActivity : AppCompatActivity() {
request: WebResourceRequest, request: WebResourceRequest,
error: WebResourceError error: WebResourceError
) { ) {
// Only show error overlay for main-frame navigation failures
if (request.isForMainFrame) { if (request.isForMainFrame) {
Log.e(TAG, "WebView error: ${error.description} (${error.errorCode})")
showError() showError()
} }
} }
// Do NOT override onReceivedSslError to proceed — let TLS override fun onReceivedHttpError(
// errors fail as they should for security. view: WebView,
request: WebResourceRequest,
errorResponse: WebResourceResponse
) {
if (request.isForMainFrame) {
Log.e(TAG, "HTTP error ${errorResponse.statusCode} for ${request.url}")
showError()
}
}
override fun onReceivedSslError(
view: WebView,
handler: SslErrorHandler,
error: android.net.http.SslError
) {
Log.e(TAG, "SSL error: ${error.primaryError} for ${error.url}")
handler.cancel()
showError()
}
} }
// ── WebChromeClient ───────────────────────────────────────────────── // ── WebChromeClient ─────────────────────────────────────────────────
private inner class ScannerWebChromeClient : WebChromeClient() { private inner class ScannerWebChromeClient : WebChromeClient() {
// File upload support: <input type="file"> in the webpage override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
Log.d(TAG, "JS [${consoleMessage.messageLevel()}] ${consoleMessage.message()} " +
"(${consoleMessage.sourceId()}:${consoleMessage.lineNumber()})")
return true
}
override fun onShowFileChooser( override fun onShowFileChooser(
webView: WebView, webView: WebView,
filePathCallback: ValueCallback<Array<Uri>>, filePathCallback: ValueCallback<Array<Uri>>,
@ -366,6 +393,7 @@ class MainActivity : AppCompatActivity() {
} }
companion object { companion object {
private const val TAG = "JoykooScanner"
private const val FILE_CHOOSER_REQUEST = 1001 private const val FILE_CHOOSER_REQUEST = 1001
} }
} }

View File

@ -5,6 +5,6 @@
android:viewportWidth="108" android:viewportWidth="108"
android:viewportHeight="108"> android:viewportHeight="108">
<path <path
android:fillColor="#1565C0" android:fillColor="#FFFFFF"
android:pathData="M0,0h108v108h-108z" /> android:pathData="M0,0h108v108h-108z" />
</vector> </vector>

View File

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<!-- QR code icon outline -->
<path
android:fillColor="#FFFFFF"
android:pathData="M30,30h18v18h-18z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M60,30h18v18h-18z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M30,60h18v18h-18z" />
<path
android:fillColor="#1A237E"
android:pathData="M33,33h12v12h-12z" />
<path
android:fillColor="#1A237E"
android:pathData="M63,33h12v12h-12z" />
<path
android:fillColor="#1A237E"
android:pathData="M33,63h12v12h-12z" />
<path
android:fillColor="#1A237E"
android:pathData="M36,36h6v6h-6z" />
<path
android:fillColor="#1A237E"
android:pathData="M66,36h6v6h-6z" />
<path
android:fillColor="#1A237E"
android:pathData="M36,66h6v6h-6z" />
<!-- Data dots -->
<path
android:fillColor="#1A237E"
android:pathData="M54,54h6v6h-6z" />
<path
android:fillColor="#1A237E"
android:pathData="M60,60h6v6h-6z" />
<path
android:fillColor="#1A237E"
android:pathData="M66,60h6v6h-6z" />
<path
android:fillColor="#1A237E"
android:pathData="M54,66h6v6h-6z" />
<path
android:fillColor="#1A237E"
android:pathData="M72,66h6v6h-6z" />
</vector>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_launcher_background" />
<item android:drawable="@drawable/ic_launcher_foreground" />
</layer-list>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" /> <background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" /> <foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 538 B

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB