Thursday, May 15, 2014

Solution: android.util.AndroidRuntimeException: requestFeature() must be called before adding content.

android.util.AndroidRuntimeException: requestFeature() must be called before adding content
at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:249)
at com.android.internal.app.AlertController.installContent(AlertController.java:234)
            at android.app.AlertDialog.onCreate(AlertDialog.java:337)
            at android.app.Dialog.dispatchOnCreate(Dialog.java:361)
            at android.app.Dialog.show(Dialog.java:262)

The following exception occurred when show() method of alertdialog box called.

The main causes is not show() of alertbox. Let’s look the source code

// AlertDialog.Builder used to create the alert box.

AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setIcon(R.drawable.ic_launcher);
alertDialogBuilder.setTitle("Full Screen...");
alertDialogBuilder.setMessage("Are you sure?");
alertDialogBuilder.setNeutralButton("OK",
                   new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
                                      dialog.cancel();
}
});
                       
// Creates a AlertDialog with the arguments supplied to this builder. It does not show() the dialog.

AlertDialog alertDialog = alertDialogBuilder.create();

// Retrieve the current Window for the activity.
// Set the flags of the window, as per the WindowManager.LayoutParams flags.
// Window flag FLAG_FULLSCREEN: hide all screen decorations (such as the status bar) while this window is displayed.

alertDialog.getWindow().setFlags(
                   WindowManager.LayoutParams.FLAG_FULLSCREEN,
                   WindowManager.LayoutParams.FLAG_FULLSCREEN);

int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                   | View.SYSTEM_UI_FLAG_FULLSCREEN;


// Retrieve the top-level window decor view (containing the standard window frame/decorations and the client's content inside of that), which can be added as a window to the window manager. Request that the visibility of the status bar or other screen/window decorations be changed.
alertDialog.getWindow().getDecorView().setSystemUiVisibility(uiOptions);

// Dialog is shown.
alertDialog.show();


Exception is occurred due to the getDecorView method, before showing the alertdialog to the user; we are trying to add content.

To solve the exception, just call the getDecorView after the alertDialog.show();

Before: (AndroidRuntimeException occurred)

alertDialog.getWindow().getDecorView().setSystemUiVisibility(uiOptions);

alertDialog.show();


After: (No Exception)

alertDialog.show();

alertDialog.getWindow().getDecorView().setSystemUiVisibility(uiOptions);


What is getDecorView()?

DecorView is nothing but View. This is an abstract method of Window class.

It retrieves the top-level window decor view, which can be added as a window to the window manager.

Where we can see getDecorView() in application?

When we call findViewById (int id), It finds a view that was identified by the id attribute from the XML that was processed in onCreate(Bundle). This will implicitly call getDecorView() for us, with all of the associated side-effects.

setSystemUiVisibility: This method is used to put the over device UI into temporary modes where the user's attention is focused more on the application content, by dimming or hiding surrounding system affordances.

When Android came up with Full-screen Immersive mode feature, the usage of setSystemUiVisibility became more popular. Where this feature is giving new ways to build beautiful apps by full-bleed UIs reaching end to end of the screen, by hiding all the system UI’s such as status bar and navigation bar, but the user swipes screen then there will be display of Semi-transparent bars which temporarily appear and then hide again.


Thanks for reading :) 
Whether this post is helpful?

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? Share it in the comments. 

No comments :

Post a Comment