Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019 Gluon
* Copyright (c) 2016, 2025, Gluon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -59,7 +59,15 @@ static Optional<StatusBarService> create() {

/**
* Sets the color of the status bar to the specified color.
* Up until Android 14
* @param color The color to set the status bar to.
*/
void setColor(Color color);

/**
* Sets the color of the status bar to the specified color, on Android 15+
* @param statusBarColor The color to set the status bar to.
* @param navigationBarColor The color to set the navigation bar to.
*/
void setSystemBarsColor(Color statusBarColor, Color navigationBarColor);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2020, Gluon
* Copyright (c) 2016, 2025, Gluon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -41,6 +41,11 @@ public void setColor(Color color) {
setNativeColor(getIntColor(color));
}

@Override
public void setSystemBarsColor(Color statusBarColor, Color navigationBarColor) {
setNativeSystemBarsColor(getIntColor(statusBarColor), getIntColor(navigationBarColor));
}

private static int getIntColor(Color color) {
if (color == null) {
return 0xff000000; // Black
Expand All @@ -54,4 +59,6 @@ private static int getIntColor(Color color) {
}

private native void setNativeColor(int color);
private native void setNativeSystemBarsColor(int statusBarColor, int navigationBarColor);

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Gluon
* Copyright (c) 2016, 2025, Gluon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -41,5 +41,10 @@ public void setColor(Color color) {
setNativeColor(color.getRed(), color.getGreen(), color.getBlue(), color.getOpacity());
}

@Override
public void setSystemBarsColor(Color statusBarColor, Color navigationBarColor) {
// to-do
}

private native void setNativeColor(double red, double green, double blue, double opacity);
}
17 changes: 15 additions & 2 deletions modules/statusbar/src/main/native/android/c/statusbar.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021, Gluon
* Copyright (c) 2020, 2025, Gluon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -30,12 +30,14 @@
static jclass jStatusBarServiceClass;
static jobject jDalvikStatusBarService;
static jmethodID jStatusBarServiceColorMethod;
static jmethodID jSystemBarsServiceColorMethod;

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

jobject jActivity = substrateGetActivity();
jobject jtmpobj = (*dalvikEnv)->NewObject(dalvikEnv, jStatusBarServiceClass, jStatusBarServiceInitMethod, jActivity);
Expand Down Expand Up @@ -77,4 +79,15 @@ JNIEXPORT void JNICALL Java_com_gluonhq_attach_statusbar_impl_AndroidStatusBarSe
}
(*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikStatusBarService, jStatusBarServiceColorMethod, color);
DETACH_DALVIK();
}
}

JNIEXPORT void JNICALL Java_com_gluonhq_attach_statusbar_impl_AndroidStatusBarService_setNativeSystemBarsColor
(JNIEnv *env, jclass jClass, jint statusBarColor, jint navigationBarColor)
{
ATTACH_DALVIK();
if (isDebugAttach()) {
ATTACH_LOG_FINE("Set native system bars color, values: %d %d", statusBarColor, navigationBarColor);
}
(*dalvikEnv)->CallVoidMethod(dalvikEnv, jDalvikStatusBarService, jSystemBarsServiceColorMethod, statusBarColor, navigationBarColor);
DETACH_DALVIK();
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowInsetsController;
import android.view.WindowManager;

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

private void setColor(final int color) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { // < 21
Log.e(TAG, "StatusBar service is not supported for the current Android version");
Log.e(TAG, "setColor is not supported for the current Android version");
return;
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // > 34
Log.e(TAG, "setColor is not supported for the current Android version. " +
"Use setSystemBarsColor instead");
return;
}
if (activity == null) {
Expand All @@ -64,29 +70,66 @@ private void setColor(final int color) {
@Override
public void run() {
Window window = activity.getWindow();
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // <= 34
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// make status bar transparent
window.setStatusBarColor(0x00000000);
// paint window
window.setBackgroundDrawable(new ColorDrawable(color));
} else { // >= 35
View decorView = window.getDecorView();

// Get insets, before applying the color, as it will reset them
int top = decorView.getPaddingTop();
int right = decorView.getPaddingRight();
int bottom = decorView.getPaddingBottom();
int left = decorView.getPaddingLeft();

// Apply color
decorView.setBackground(new ColorDrawable(color));

// Restore insets
decorView.setPadding(left, top, right, bottom);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// make status bar transparent
window.setStatusBarColor(0x00000000);
// paint window
window.setBackgroundDrawable(new ColorDrawable(color));
}
});
}

private void setSystemBarsColor(final int statusBarColor, final int navigationBarColor) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // < 34
Log.e(TAG, "setSystemBarsColor is not supported for the current Android version. " +
"Use setColor instead");
return;
}
if (activity == null) {
Log.e(TAG, "FXActivity not found. This service is not allowed when "
+ "running in background mode or from wearable");
return;
}

if (Util.isDebug()) {
Log.v(TAG, "Set SystemBars color, values: " + statusBarColor + ", " + navigationBarColor);
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Window window = activity.getWindow();
View decorView = window.getDecorView();

// Get insets, before applying the color, as it will reset them
int top = decorView.getPaddingTop();
int right = decorView.getPaddingRight();
int bottom = decorView.getPaddingBottom();
int left = decorView.getPaddingLeft();

WindowInsetsController windowInsetsController = decorView.getWindowInsetsController();
if (windowInsetsController != null) {
// background light color requires dark icons, dark light color, white icons
int bitset = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
windowInsetsController.setSystemBarsAppearance(getLuma(statusBarColor) > 128 ?
bitset : 0, bitset);
}

// Apply colors
decorView.setBackground(new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
new int[]{statusBarColor, navigationBarColor}));

// Restore insets
decorView.setPadding(left, top, right, bottom);
}
});
}

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

}