Keep the system splash until the first real screen: no blank WebView gap, no second splash
Installed APK sequence was system splash -> white WebView -> web splash -> home. The activity now holds the system splash (core-splashscreen) until the page calls TadrisinoAndroid.appReady(), after its first non-boot screen; released after 10s or on a main-frame load error so a dead site shows the WebView error, not an endless splash. Older APKs have no appReady and are unaffected. Debug build compiles; not run on a device. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.Tadrisino.Starting"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -5,6 +5,8 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import android.os.VibratorManager
|
||||
@@ -15,6 +17,7 @@ import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import ir.cafebazaar.poolakey.Connection
|
||||
import ir.cafebazaar.poolakey.Payment
|
||||
import ir.cafebazaar.poolakey.config.PaymentConfiguration
|
||||
@@ -41,6 +44,13 @@ import org.json.JSONObject
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var webView: WebView
|
||||
|
||||
/**
|
||||
* اسپلشِ سیستم تا وقتی true نشده روی صفحه میماند. فرانت وقتی اولین صفحهی واقعی (ورود/خانه) کشیده شد
|
||||
* `TadrisinoAndroid.appReady()` را صدا میزند. اگر هرگز نرسید (سایت بالا نیامد، JS خطا داد) بعد از
|
||||
* SPLASH_MAX_MS رها میشود تا کاربر بهجای اسپلشِ بیانتها صفحهی خطای WebView را ببیند، نه چیزِ دیگر.
|
||||
*/
|
||||
@Volatile private var webReady = false
|
||||
private var payment: Payment? = null
|
||||
private var connection: Connection? = null
|
||||
private val webHost: String = Uri.parse(BuildConfig.WEB_URL).host ?: ""
|
||||
@@ -59,6 +69,11 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
installSplashScreen().setKeepOnScreenCondition { !webReady }
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
if (!webReady) Log.w(TAG, "web app never reported ready; releasing the splash after ${SPLASH_MAX_MS}ms")
|
||||
webReady = true
|
||||
}, SPLASH_MAX_MS)
|
||||
super.onCreate(savedInstanceState)
|
||||
webView = WebView(this)
|
||||
setContentView(webView)
|
||||
@@ -71,6 +86,11 @@ class MainActivity : AppCompatActivity() {
|
||||
// صداهای کوتاهِ رابط (Web Audio) بعد از پاسخِ سرور پخش میشوند، نه درست در لحظهی لمس.
|
||||
webView.settings.mediaPlaybackRequiresUserGesture = false
|
||||
webView.webViewClient = object : WebViewClient() {
|
||||
// صفحهی اصلی بالا نیامد (نبودِ شبکه): اسپلش را رها کن تا خطای WebView دیده شود، نه ۱۰ ثانیه انتظار.
|
||||
override fun onReceivedError(view: WebView, request: WebResourceRequest, error: android.webkit.WebResourceError) {
|
||||
if (request.isForMainFrame) webReady = true
|
||||
}
|
||||
|
||||
// هر آدرسی بیرونِ دامنهی خودمان در مرورگرِ گوشی باز میشود، نه داخلِ اپ؛ پس پل فقط
|
||||
// در صفحههای خودمان در دسترس است.
|
||||
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
|
||||
@@ -205,6 +225,12 @@ class MainActivity : AppCompatActivity() {
|
||||
else @Suppress("DEPRECATION") vibrator.vibrate(timings, -1)
|
||||
}
|
||||
|
||||
/** فرانت اولین صفحهی واقعی را کشید؛ اسپلشِ سیستم میتواند برود. */
|
||||
@JavascriptInterface
|
||||
fun appReady() {
|
||||
webReady = true
|
||||
}
|
||||
|
||||
/** فرانت با این میفهمد درگاه داخلِ اپ باز میشود (isPaymentPage)، نه در مرورگرِ بیرونی. */
|
||||
@JavascriptInterface
|
||||
fun paysInApp(): Boolean = true
|
||||
@@ -225,5 +251,6 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "Tadrisino"
|
||||
private const val SPLASH_MAX_MS = 10_000L
|
||||
}
|
||||
}
|
||||
|
||||
BIN
android/app/src/main/res/drawable-nodpi/splash_icon_art.png
Normal file
BIN
android/app/src/main/res/drawable-nodpi/splash_icon_art.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
8
android/app/src/main/res/drawable/splash_icon.xml
Normal file
8
android/app/src/main/res/drawable/splash_icon.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- همان تصویرِ آیکونِ اپ؛ حاشیه برای اینکه ماسکِ گردِ اندروید ۱۲ گوشههایش را نبُرد. -->
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:drawable="@drawable/splash_icon_art"
|
||||
android:insetLeft="22%"
|
||||
android:insetTop="22%"
|
||||
android:insetRight="22%"
|
||||
android:insetBottom="22%" />
|
||||
@@ -4,4 +4,15 @@
|
||||
<item name="android:statusBarColor">#ED6956</item>
|
||||
<item name="android:windowBackground">@android:color/white</item>
|
||||
</style>
|
||||
|
||||
<!--
|
||||
اسپلشِ سیستم: آیکونِ اپ روی سفید، تا وقتی صفحهی وب خودش بگوید آماده است (appReady) روی صفحه میماند.
|
||||
پیش از این، اسپلش میآمد، بعد WebView سفیدِ خالی تا رسیدنِ HTML، بعد اسپلشِ وب، بعد خانه.
|
||||
سفید است چون windowBackgroundِ پایین هم سفید است و اسپلشِ وب (index.html) هم سفید است.
|
||||
-->
|
||||
<style name="Theme.Tadrisino.Starting" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@android:color/white</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
|
||||
<item name="postSplashScreenTheme">@style/Theme.Tadrisino</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user