I need to override status bar for one of my applications.
Previously, when I using targetSdkVersion
21, the code block was working perfectly but when I switched targetSdkVersion
to 30, it crashes with the following error:
2021-08-16 17:50:40.920 6309-6309/myapp.com E/AndroidRuntime: FATAL EXCEPTION: main
Process: myapp.com, PID: 6309
java.lang.RuntimeException: Unable to create application myapp.com.App: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@47a3c01 -- permission denied for this window type
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6325)
at android.app.ActivityThread.access$1800(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1862)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7230)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@47a3c01 -- permission denied for this window type
at android.view.ViewRootImpl.setView(ViewRootImpl.java:878)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:337)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:109)
at myapp.com.App.showCustomStatusBar(App.java:144)
at myapp.com.App.onCreate(App.java:67)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1037)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6322)
at android.app.ActivityThread.access$1800(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1862)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7230)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Here is the code to show the status bar:
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
if(customToolbar == null) {
customToolbar = new CustomToolbar(getBaseContext());
}
int viewType;
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
getStatusBarHeight(),
// Allows the view to be on top of the StatusBar
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
// Keeps the button presses from going to the background window
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// Enables the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.OPAQUE);
layoutParams.gravity = Gravity.TOP|Gravity.CENTER;
windowManager.addView(customToolbar, layoutParams); //Crashes on this line
I tried using :
int viewType;
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
viewType = WindowManager.LayoutParams.TYPE_PHONE;
} else {
viewType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}
instead of :
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR
But it crashes the same way.
I have also added Permissions
to manifest :
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />