41

How do you make an app with an actual fullscreen capabilities, that has the layout to be rendered underneath the notch?

Here's what I want:

Google Photos

Here's the code of what I've tried:

class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
//            window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)

            val attrib = window.attributes
            attrib.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS

            layout_main.setOnApplyWindowInsetsListener { _, windowInsets ->
                val inset = windowInsets.displayCutout
                Log.d("Tag", "Inset: $inset")
                windowInsets
            }
        }
    }
}

The layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#3000FFFF"
    android:fitsSystemWindows="true">

    <View
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="#FFFF0000"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="#FF00FF00"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="#FF0000FF"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <View
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="#FFFF00"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:gravity="center"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

The style:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <item name="android:windowNoTitle">true</item>
    <item name="android:windowActionBar">false</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>

    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

Here's the Android Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.app.testandroidp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name="com.app.testandroidp.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

Here's the result that I've gotten so far:

enter image description here

I've tried setting different themes, setting the fullscreen flag in XML / Kotlin, setting the resizable activity in manifest, but the activity just won't get rendered under the notch.

For reference, this is the project's source code: https://gitlab.com/alvin.rusli/AndroidPTest

Alvin Rusli
  • 1,026
  • 1
  • 11
  • 19

10 Answers10

50

Set these properties in your theme :

<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
Sofiane Majdoub
  • 826
  • 1
  • 9
  • 12
25

I tried lot's of things but didn't get any success, then I try the following code and it's working fine.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        }

      ---
    }

I hope it's helpful.

Sanjay Chauhan
  • 893
  • 7
  • 13
19

I finally found out why. For some strange reason, the application won't enter the if condition:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    // It never gets here
}

I removed that if condition and the activity finally goes fullscreen correctly.

Activity underneath the notch


Here are the bare minimum codes required to render the activity fullscreen.

Activity:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // or add <item name="android:windowTranslucentStatus">true</item> in the theme
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)

        val attrib = window.attributes
        attrib.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
    }
}

Styles:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <!-- Adding fullscreen will just hide the status bar -->
    <!-- <item name="android:windowFullscreen">true</item> -->
</style>
Alvin Rusli
  • 1,026
  • 1
  • 11
  • 19
  • 2
    Yeah, the version code returned by the emulator is still 27. Lint gives you incorrect fixes, you basically have to @SuppressLint("NewAPI") everywhere... – rockgecko Mar 12 '18 at 05:28
  • 1
    I think `LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS` was replaced with `LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES` : https://developer.android.com/reference/android/view/WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES . Is it true? Is it the same meaning? That it will take entire screen, including the unsafe areas? – android developer Jun 13 '18 at 13:57
  • @androiddeveloper I tested updating the code, and changing the ALWAYS to the new SHORT_EDGES work just like before, but now I wonder what you have to do to make a complete fullscreen view for that "double cutout" notches – Alvin Rusli Jun 26 '18 at 08:11
  • @AlvinRusli For that, you can have 2 options: immersive mode, as shown here: https://developer.android.com/training/system-ui/immersive . Or, if you want to show the navigation bar, use this: https://stackoverflow.com/a/29138275/878126 , including this in code: `window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)` – android developer Jun 26 '18 at 09:19
  • @androiddeveloper Got it, `window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION` works, thanks! – Alvin Rusli Jul 06 '18 at 04:28
  • I think `MODE_SHORT_EDGES` will always behave just like `MODE_ALWAYS` because for now cutouts are only permitted on short edges of devices. From the documentation of DisplayCutout.getBoundingRects "There will be at most one non-functional area per short edge of the device, and none on the long edges.". Clearly by renaming `MODE_ALWAYS`, google are leaving the door open for notches to start appearing on long edges in future API revisions, but for now we're safe. – Columbo Jul 25 '18 at 13:00
  • Is there no XML equivalent to `attrib.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS`? – Michael Jan 04 '19 at 18:19
  • This won't work if we are supporting minimum API <28 so we can't remove the if condition. How else will the app know whether to use the condition or not? – Subham Burnwal Nov 27 '19 at 13:18
  • @AlvinRusli How about in landscape mode, is it fixed? – Ashraf Alshahawy Oct 14 '20 at 07:17
15

if nothing works then try this one once

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }
saigopi.me
  • 14,011
  • 2
  • 83
  • 54
9

This is what worked for me:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
        getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
    }
LachoTomov
  • 3,312
  • 30
  • 42
8

I`m having same problem while developing App for Notch Device, i cater this issue by defining the theme style for android P devices and set the mode like default,shortEdges,never mode.

Step 1: Create a new values-v28 folder in your res directory and copy the default styles.xml file into it.

Step 2: In the values-28 variant of the styles.xml file, go to your Activity’s theme or create a new one if you’ve been using the default one, and set this attribute:

<style name="ActivityTheme">
  <item name="android:windowLayoutInDisplayCutoutMode">
    shortEdges
  </item>
</style>

That’s all you have to do to get a more immersive experience in your app and avoid letterboxing by making the app’s window render on either side areas of the notch.

enter image description here

Here is the link to learn more about Developing Compatible App for Notch Devices. Making Notch Friendly Apps

Asad Mukhtar
  • 391
  • 6
  • 18
3

below code worked for me, I hope it works for you too:

protected void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE);//will hide the title
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //show the activity in full screen
    setContentView(R.layout.activity_pdf_view);

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }
}
    
necip
  • 333
  • 4
  • 11
2

If you want to apply it everywhere in your app then there is a simpler solution according to Android Documentation:

Add this item in your theme file(s)

  <item name="android:windowLayoutInDisplayCutoutMode">
    shortEdges <!-- default, shortEdges, or never -->
  </item>

See more at this Android Documentation

Akhil Hothi
  • 67
  • 10
1

That is because you were using Android P when it wasn't officially released yet.

You probably have a Developer Preview that has some issues with the vendor. If you search Google for your system and find an XDA page, you may be able to see "Vendor" listed among the bugs of your ROM.

Usually, Developer Previews keep the vendor of the previous Android version, which means your app thinks to be in Android Oreo, when you're checking for it in the following line:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
Davide Cannizzo
  • 2,826
  • 1
  • 29
  • 31
0

Try following style ,

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
</style>
Lucifer
  • 29,392
  • 25
  • 90
  • 143