Safe Area Insets not returned correctly for Android

Hi Folks,

I am trying to get safe area insets for android phones, so that I can prevent drawing my app under those blocked areas like notches and all. I am using this code which is working fine for iOS devices.

auto safeAreaInsets = juce::Desktop::getInstance().getDisplays().getPrimaryDisplay()->safeAreaInsets;

For android, its not giving correct safe area insets. I tried making a native application in Android Studio and its respecting the safe area insets. Here is the following code generated by Android Studio.

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
    }
}

How to implement this things in juce so that it will return correct safe area insets, so that I will draw only in safe area by subtracting this insets from local bounds.

This is very basic functionality which one would expect the framework to handle perfectly. There have been numerous threads since at least 2019 pointing these problems out but there has not been a response from anyone from the JUCE team on any of those threads.

This is on my radar. At the moment I’m focusing on MIDI 2.0, but I’m planning to investigate Android safe display areas after that.

That’s great, thank you!

Some updates:

We now do a better job of respecting safe screen areas in demo projects generated from PIPs. Such projects should now avoid placing demo content beneath notches and other screen decorations:

We’ve also updated our Android safe-area handling:

On all Android versions, we’ve switched to displaying content “edge-to-edge”, which in practice means that JUCE apps will always draw behind the status and navigation bars. On Android 15 and above, this behaviour is enforced, and we back-ported it to keep the behaviour as consistent as possible between Android versions. As a result of this change, it’s now extremely important to handle the safeAreaInsets correctly, as it’s now much more likely that content will render behind the system UI if these insets are ignored.

Finally, we’ve updated the SidePanel component to avoid areas of the screen that might be obscured. This makes the DemoRunner more usable on iPhones and Androids with screen notches:

2 Likes

I have tested this today and everything works as expected. Thank you very much!

1 Like

That’s wonderful to hear!

Weirdly, when I just tried evaluating this when looking at the JUCE 8 develop tip, it worked fine for my test when using an SDK 36 emulator, but displayed my app with a tiny window when using an emulator for SDK 35 or SDK 34 (the oldest I went back to). If anybody else spots this behaviour, do please let me know!

I decided to look again at this, and found the “tiny window” problem was due to my not calling setKioskModeComponent for the main window component. No such issue for SDK 36 emulators!