Skip to content

Commit 4d3f5e6

Browse files
authored
Add setSytemBarsColor API (#433)
* Add setSytemBarsColor API * limit sdk
1 parent 315c389 commit 4d3f5e6

File tree

5 files changed

+102
-26
lines changed

5 files changed

+102
-26
lines changed

modules/statusbar/src/main/java/com/gluonhq/attach/statusbar/StatusBarService.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019 Gluon
2+
* Copyright (c) 2016, 2025, Gluon
33
*
44
* This program is free software: you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License as published by
@@ -59,7 +59,15 @@ static Optional<StatusBarService> create() {
5959

6060
/**
6161
* Sets the color of the status bar to the specified color.
62+
* Up until Android 14
6263
* @param color The color to set the status bar to.
6364
*/
6465
void setColor(Color color);
66+
67+
/**
68+
* Sets the color of the status bar to the specified color, on Android 15+
69+
* @param statusBarColor The color to set the status bar to.
70+
* @param navigationBarColor The color to set the navigation bar to.
71+
*/
72+
void setSystemBarsColor(Color statusBarColor, Color navigationBarColor);
6573
}

modules/statusbar/src/main/java/com/gluonhq/attach/statusbar/impl/AndroidStatusBarService.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2020, Gluon
2+
* Copyright (c) 2016, 2025, Gluon
33
*
44
* This program is free software: you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License as published by
@@ -41,6 +41,11 @@ public void setColor(Color color) {
4141
setNativeColor(getIntColor(color));
4242
}
4343

44+
@Override
45+
public void setSystemBarsColor(Color statusBarColor, Color navigationBarColor) {
46+
setNativeSystemBarsColor(getIntColor(statusBarColor), getIntColor(navigationBarColor));
47+
}
48+
4449
private static int getIntColor(Color color) {
4550
if (color == null) {
4651
return 0xff000000; // Black
@@ -54,4 +59,6 @@ private static int getIntColor(Color color) {
5459
}
5560

5661
private native void setNativeColor(int color);
62+
private native void setNativeSystemBarsColor(int statusBarColor, int navigationBarColor);
63+
5764
}

modules/statusbar/src/main/java/com/gluonhq/attach/statusbar/impl/IOSStatusBarService.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019, Gluon
2+
* Copyright (c) 2016, 2025, Gluon
33
*
44
* This program is free software: you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License as published by
@@ -41,5 +41,10 @@ public void setColor(Color color) {
4141
setNativeColor(color.getRed(), color.getGreen(), color.getBlue(), color.getOpacity());
4242
}
4343

44+
@Override
45+
public void setSystemBarsColor(Color statusBarColor, Color navigationBarColor) {
46+
// to-do
47+
}
48+
4449
private native void setNativeColor(double red, double green, double blue, double opacity);
4550
}

modules/statusbar/src/main/native/android/c/statusbar.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2021, Gluon
2+
* Copyright (c) 2020, 2025, Gluon
33
*
44
* This program is free software: you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License as published by
@@ -30,12 +30,14 @@
3030
static jclass jStatusBarServiceClass;
3131
static jobject jDalvikStatusBarService;
3232
static jmethodID jStatusBarServiceColorMethod;
33+
static jmethodID jSystemBarsServiceColorMethod;
3334

3435
static void initializeStatusBarDalvikHandles() {
3536
jStatusBarServiceClass = GET_REGISTER_DALVIK_CLASS(jStatusBarServiceClass, "com/gluonhq/helloandroid/DalvikStatusBarService");
3637
ATTACH_DALVIK();
3738
jmethodID jStatusBarServiceInitMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jStatusBarServiceClass, "<init>", "(Landroid/app/Activity;)V");
3839
jStatusBarServiceColorMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jStatusBarServiceClass, "setColor", "(I)V");
40+
jSystemBarsServiceColorMethod = (*dalvikEnv)->GetMethodID(dalvikEnv, jStatusBarServiceClass, "setSystemBarsColor", "(II)V");
3941

4042
jobject jActivity = substrateGetActivity();
4143
jobject jtmpobj = (*dalvikEnv)->NewObject(dalvikEnv, jStatusBarServiceClass, jStatusBarServiceInitMethod, jActivity);
@@ -77,4 +79,15 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_statusbar_impl_AndroidStatusBarSe
7779
}
7880
(*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikStatusBarService, jStatusBarServiceColorMethod, color);
7981
DETACH_DALVIK();
80-
}
82+
}
83+
84+
JNIEXPORT void JNICALL Java_com_gluonhq_attach_statusbar_impl_AndroidStatusBarService_setNativeSystemBarsColor
85+
(JNIEnv *env, jclass jClass, jint statusBarColor, jint navigationBarColor)
86+
{
87+
ATTACH_DALVIK();
88+
if (isDebugAttach()) {
89+
ATTACH_LOG_FINE("Set native system bars color, values: %d %d", statusBarColor, navigationBarColor);
90+
}
91+
(*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikStatusBarService, jSystemBarsServiceColorMethod, statusBarColor, navigationBarColor);
92+
DETACH_DALVIK();
93+
}

modules/statusbar/src/main/native/android/dalvik/DalvikStatusBarService.java

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@
3030
import android.app.Activity;
3131
import android.content.Context;
3232
import android.graphics.drawable.ColorDrawable;
33+
import android.graphics.drawable.GradientDrawable;
3334
import android.os.Build;
3435
import android.util.Log;
3536
import android.view.View;
3637
import android.view.Window;
38+
import android.view.WindowInsetsController;
3739
import android.view.WindowManager;
3840

3941
public class DalvikStatusBarService {
@@ -48,7 +50,11 @@ public DalvikStatusBarService(Activity activity) {
4850

4951
private void setColor(final int color) {
5052
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { // < 21
51-
Log.e(TAG, "StatusBar service is not supported for the current Android version");
53+
Log.e(TAG, "setColor is not supported for the current Android version");
54+
return;
55+
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // > 34
56+
Log.e(TAG, "setColor is not supported for the current Android version. " +
57+
"Use setSystemBarsColor instead");
5258
return;
5359
}
5460
if (activity == null) {
@@ -64,29 +70,66 @@ private void setColor(final int color) {
6470
@Override
6571
public void run() {
6672
Window window = activity.getWindow();
67-
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // <= 34
68-
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
69-
// make status bar transparent
70-
window.setStatusBarColor(0x00000000);
71-
// paint window
72-
window.setBackgroundDrawable(new ColorDrawable(color));
73-
} else { // >= 35
74-
View decorView = window.getDecorView();
75-
76-
// Get insets, before applying the color, as it will reset them
77-
int top = decorView.getPaddingTop();
78-
int right = decorView.getPaddingRight();
79-
int bottom = decorView.getPaddingBottom();
80-
int left = decorView.getPaddingLeft();
81-
82-
// Apply color
83-
decorView.setBackground(new ColorDrawable(color));
84-
85-
// Restore insets
86-
decorView.setPadding(left, top, right, bottom);
73+
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
74+
// make status bar transparent
75+
window.setStatusBarColor(0x00000000);
76+
// paint window
77+
window.setBackgroundDrawable(new ColorDrawable(color));
78+
}
79+
});
80+
}
81+
82+
private void setSystemBarsColor(final int statusBarColor, final int navigationBarColor) {
83+
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // < 34
84+
Log.e(TAG, "setSystemBarsColor is not supported for the current Android version. " +
85+
"Use setColor instead");
86+
return;
87+
}
88+
if (activity == null) {
89+
Log.e(TAG, "FXActivity not found. This service is not allowed when "
90+
+ "running in background mode or from wearable");
91+
return;
92+
}
93+
94+
if (Util.isDebug()) {
95+
Log.v(TAG, "Set SystemBars color, values: " + statusBarColor + ", " + navigationBarColor);
96+
}
97+
activity.runOnUiThread(new Runnable() {
98+
@Override
99+
public void run() {
100+
Window window = activity.getWindow();
101+
View decorView = window.getDecorView();
102+
103+
// Get insets, before applying the color, as it will reset them
104+
int top = decorView.getPaddingTop();
105+
int right = decorView.getPaddingRight();
106+
int bottom = decorView.getPaddingBottom();
107+
int left = decorView.getPaddingLeft();
108+
109+
WindowInsetsController windowInsetsController = decorView.getWindowInsetsController();
110+
if (windowInsetsController != null) {
111+
// background light color requires dark icons, dark light color, white icons
112+
int bitset = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
113+
windowInsetsController.setSystemBarsAppearance(getLuma(statusBarColor) > 128 ?
114+
bitset : 0, bitset);
87115
}
116+
117+
// Apply colors
118+
decorView.setBackground(new GradientDrawable(
119+
GradientDrawable.Orientation.TOP_BOTTOM,
120+
new int[]{statusBarColor, navigationBarColor}));
121+
122+
// Restore insets
123+
decorView.setPadding(left, top, right, bottom);
88124
}
89125
});
90126
}
91127

128+
private static double getLuma(int color) {
129+
int r = (color >> 16) & 0xff;
130+
int g = (color >> 8) & 0xff;
131+
int b = (color >> 0) & 0xff;
132+
return 0.2126 * r + 0.7152 * g + 0.0722 * b; // 0 darkest - 255 lightest
133+
}
134+
92135
}

0 commit comments

Comments
 (0)