capacitor-plugins icon indicating copy to clipboard operation
capacitor-plugins copied to clipboard

`StatusBar.setOverlaysWebView({ overlay: true })` alongside SplashScreen glitches on Android API 33 (Android 13)

Open jbouchard24 opened this issue 2 years ago • 13 comments

Bug Report

Plugin(s)

Capacitor Version

   Capacitor Doctor   

Latest Dependencies:

  @capacitor/cli: 4.1.0
  @capacitor/core: 4.1.0
  @capacitor/android: 4.1.0
  @capacitor/ios: 4.1.0

Installed Dependencies:

  @capacitor/ios: not installed
  @capacitor/cli: 4.1.0
  @capacitor/android: 4.1.0
  @capacitor/core: 4.1.0

[success] Android looking great! 👌

Platform(s)

Current Behavior

I have an app that uses the StatusBar.setOverlaysWebView({ overlay: true }) feature from the StatusBar plugin, alongside the SplashScreen plugin. When opening the app on Android API 33 (Android 13) from home screen or app drawer, the status bar is opaque and the webview stretches underneath the navigation/gesture bar. That is not the case on Android API 31 (Android 12) or earlier, or when opening the app from settings > Apps or long-pressing the app icon > App Info > Open. (See Additional context for more info)

Current behavior on Android API 33 (Android 13): image

Expected Behavior

I expect a behavior like Android API 31 (Android 12) and earlier, where the app is using the space underneath a transparent status bar and the bottom doesn't stretch past the gesture bar when calling StatusBar.setOverlaysWebView({ overlay: true }): image

Code Reproduction

Example repo

Additional Context

Here some of the tests I made. Hopefully it helps isolate the issue.

Working: ✅

  • Android API 31 and earlier
  • StatusBar plugin alone (no SplashScreen plugin)
  • Android API 33 when long-pressing the app icon > App Info > Open

Not working: ❌

  • Android API 33 when opening from home screen or app drawer

jbouchard24 avatar Aug 29 '22 13:08 jbouchard24

This issue may need more information before it can be addressed. In particular, it will need a reliable Code Reproduction that demonstrates the issue.

Please see the Contributing Guide for how to create a Code Reproduction.

Thanks! Ionitron 💙

Ionitron avatar Aug 29 '22 14:08 Ionitron

Code Repro has been updated from a list of steps to an example repo

jbouchard24 avatar Aug 29 '22 14:08 jbouchard24

@jbouchard24 I've got the same issue and this fix seems to work in this case. This part in particular:

MainActivity.kt:

import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen

class MainActivity : BridgeActivity() {
  public override fun onCreate(savedInstanceState: Bundle?) {
    registerPlugins(
      // ...
    )
    super.onCreate(savedInstanceState)
    // This line fixes the issue:
    val splashScreen = installSplashScreen()
  }
}

nikitalpopov avatar Sep 07 '22 16:09 nikitalpopov

@nikitalpopov Thanks for the reply, but it's not working in my project.

I have been suggested to make changes to the status bar in a setTimeout after hiding the splash screen. I don't like the fix, but at least it's working in my case:

await SplashScreen.hide();
setTimeout(async () => {
    await StatusBar.setOverlaysWebView({ overlay: true });
}, 500);

jbouchard24 avatar Oct 12 '22 12:10 jbouchard24

setTimeout(async () => { await StatusBar.setOverlaysWebView({ overlay: true }); }, 500);

Yes after a ton of googling and whatnot this is what i've had to resort to aswell, my issue was with StatusBar.setBackgroundColor not setting the correct statusbar color on app launch (the statusbar background is supposed to be white or black depending on whether the user last chose dark or light theme for the app, and when the user toggles themes in the app the statusbar background color changes between white and black just fine), putting a settimeout to occur 250ms after the splashscreen is hidden did the trick, feels a bit hacky and i was still looking for a proper fix but it doesn't look like there is one so this will have to do.

mpmua avatar Sep 26 '23 08:09 mpmua

Still an issue for me with version 5.0.6

sam-higgs avatar Nov 17 '23 15:11 sam-higgs

tested on ionic/vue very clean

  onMounted(() => {
    Device.getInfo().then((info) => {
      if (info.platform !== 'web') {
        SplashScreen.hide().then(() => {
          setTimeout(() => {
            StatusBar.setOverlaysWebView({ overlay: true })
          }, 100)
        })
      }
    })
  })

with capacitor.config.ts

import { CapacitorConfig } from '@capacitor/cli'

const config: CapacitorConfig = {
appId: 'io.ionic.starter',
appName: 'E-Kampoeng',
webDir: 'dist',
server: {
  androidScheme: 'https',
},
plugins: {
  SplashScreen: {
    launchShowDuration: 30000,
    // launchAutoHide: true,
    launchFadeOutDuration: 900,
    backgroundColor: '#ffffffff',
    // androidSplashResourceName: 'splash',
    // androidScaleType: 'CENTER_CROP',
    showSpinner: false,
    androidSpinnerStyle: 'small',
    iosSpinnerStyle: 'small',
    spinnerColor: '#999999',
    splashFullScreen: true,
    splashImmersive: true,
    layoutName: 'launch_screen',
    // useDialog: true,
  },
},
}

export default config

aacassandra avatar Jan 09 '24 22:01 aacassandra

Still an issue for me with version 5.0.6, react/ionic - I tried all proposed approach above? it did not work with my project. Has anyone solved this issue? please give me a hint to overcome it or when this issue will be fixed. Thank you!

haily2706 avatar Jan 21 '24 05:01 haily2706

Using Angular here, best solution I found is to set splashscreen duration to some reasonable time:

SplashScreen:{    
      launchShowDuration:2300
  },

and in my app.component.ts:

this.platform.ready().then(()=>{     
     setTimeout(async()=>{
      await StatusBar.setOverlaysWebView({ overlay: true });
    },2300)
    })

it works every time. And it is better than doing it with this approach:

await SplashScreen.hide();
   setTimeout(async () => {
   await StatusBar.setOverlaysWebView({ overlay: true });
}, 500);

,because this way you will have blank white screen for short amount of time between splashscreen and app home screen.

prdjed avatar Feb 05 '24 13:02 prdjed

@nikitalpopov Thanks for the reply, but it's not working in my project.

I have been suggested to make changes to the status bar in a setTimeout after hiding the splash screen. I don't like the fix, but at least it's working in my case:

await SplashScreen.hide();
setTimeout(async () => {
    await StatusBar.setOverlaysWebView({ overlay: true });
}, 500);

thank you so much!!

Dayonel avatar Feb 18 '24 15:02 Dayonel

The issue still does exist, all methods of StatusBar are affected.

The following solution is working for me:

capacitor.config.ts

/// <reference types="@capacitor/splash-screen" />

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  ...
  plugins: {
    SplashScreen: {
      launchShowDuration: 1000,
    }
  }

Call any methods of StatusBar after the specified launchShowDuration:

setTimeout(() => {
  if (Capacitor.isPluginAvailable('StatusBar')) {
    StatusBar.setBackgroundColor({ color: '#001358'}).then().catch()
    StatusBar.setStyle({ style: Style.Dark }).then().catch()
  }
}, 1000)

I am using `"@capacitor/status-bar": "^5.0.6",

mleister97 avatar May 31 '24 10:05 mleister97

Just FYI the issue still exists on "@capacitor/status-bar": "6.0.0". It took me 2 days to find this github issue and try out the suggested timeout, equal to the launchShowDuration that finally makes it work for me too. Maybe until a proper fix is introduced this "workaround" should also be included in the documentation of the status-bar plugin.

dimeloper avatar Jun 25 '24 22:06 dimeloper