I'm using Immersive Mode in my app when it's running on Android 4.4+. (http://developer.android.com/training/system-ui/immersive.html)
My activity indeed shows in full screen, and I work around the volume key pressing by using setOnSystemUiVisibilityChangeListener. I also have similar code for putting dialogs into immersive mode.
However, when a dialog is shown, the nav. bars jump on the screen and then retreat immediately. When the dialog is dismissed it's even worse - the nav. bars jump and resize the activity behind.
The following is my class for supporting immersive mode. It is simply called on each Activity's onResume and also a separate function is called when building each dialog.
Did I miss any flag or callback, or is it a known Android issue?
public class ImmersiveModeHelper {
    public ImmersiveModeHelper(Activity activity)
    {
        mActivity = activity;
    }
    @SuppressLint("NewApi")
    public void supportFullScreenImmersiveMode()
    {
        MyLog.d("ImmersiveModeHelper: supportFullScreenImmersiveMode: ");
        // Support full-screen immersive mode on Android 4.4 and up
        if (Build.VERSION.SDK_INT >= 19)
        {
            // Get the needed flags by reflection and use them
            try
            {
                final int immersiveFlag = View.class.getField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY")
                        .getInt(null);
                final int hideNavigationFlag = View.class
                        .getField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
                final int fullScreenFlag = View.class.getField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(
                        null);
                // Set the flags to the window decor view
                mActivity.getWindow().getDecorView()
                        .setSystemUiVisibility(immersiveFlag | hideNavigationFlag | fullScreenFlag);
                // Set a callback to be called when visibility changes
                // (workaround
                // for volume keys)
                mActivity
                        .getWindow()
                        .getDecorView()
                        .setOnSystemUiVisibilityChangeListener(
                                new View.OnSystemUiVisibilityChangeListener()
                                {
                                    @Override
                                    public void onSystemUiVisibilityChange(int visibility)
                                    {
                                        MyLog.d("ImmersiveModeHelper.supportFullScreenImmersiveMode().new OnSystemUiVisibilityChangeListener() {...}: onSystemUiVisibilityChange: " +
                                                "");
                                        if ((visibility & (immersiveFlag | hideNavigationFlag)) == 0)
                                        {
                                            Handler uiHandler = UiThreadUtils.getUiHandler();
                                            uiHandler.removeCallbacks(mHideSystemUiCallback);
                                            uiHandler.postDelayed(mHideSystemUiCallback,
                                                    HIDE_SYSTEM_UI_DELAY_MILLI);
                                        }
                                    }
                                });
            } catch (Exception e)
            {
                e.printStackTrace();
                MyLog.e("ImmersiveModeHelper: supportFullScreenImmersiveMode: couldn't support immersive mode by reflection");
            }
        } else
        {
            MyLog.i("ImmersiveModeHelper: supportFullScreenImmersiveMode: not supported on this platform version");
        }
    }
    public static void supportFullScreenImmersiveModeForDialog(final Dialog dlg)
    {
        MyLog.d("ImmersiveModeHelper: supportFullScreenImmersiveModeForDialog: ");
        // Support full-screen immersive mode on Android 4.4 and up
        if (Build.VERSION.SDK_INT >= 19)
        {
            final Window dlgWindow = dlg.getWindow();
            // Get the needed flags by reflection and use them
            try
            {
                final int immersiveFlag = View.class.getField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY")
                        .getInt(null);
                final int hideNavigationFlag = View.class
                        .getField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
                final int fullScreenFlag = View.class.getField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(
                        null);
                // Set the flags to the window decor view
                int flags = dlgWindow.getDecorView().getSystemUiVisibility();
                flags |= (immersiveFlag | hideNavigationFlag | fullScreenFlag);
                dlgWindow.getDecorView().setSystemUiVisibility(flags);
                // Set a callback to be called when visibility changes
                // (workaround for volume keys)
                dlgWindow.getDecorView().setOnSystemUiVisibilityChangeListener(
                        new View.OnSystemUiVisibilityChangeListener()
                        {
                            @Override
                            public void onSystemUiVisibilityChange(int visibility)
                            {
                                MyLog.d("ImmersiveModeHelper.supportFullScreenImmersiveModeForDialog(...).new OnSystemUiVisibilityChangeListener() {...}: onSystemUiVisibilityChange: ");
                                if ((visibility & (immersiveFlag | hideNavigationFlag)) == 0)
                                {
                                    Runnable hideSystemUiCallback = new Runnable()
                                    {
                                        @Override
                                        public void run()
                                        {
                                            supportFullScreenImmersiveModeForDialog(dlg);
                                        }
                                    };
                                    Handler uiHandler = UiThreadUtils.getUiHandler();
                                    uiHandler.removeCallbacks(hideSystemUiCallback);
                                    uiHandler.postDelayed(hideSystemUiCallback,
                                            HIDE_SYSTEM_UI_DELAY_MILLI);
                                }
                            }
                        });
            } catch (Exception e)
            {
                e.printStackTrace();
                MyLog.e("ImmersiveModeHelper: supportFullScreenImmersiveMode: couldn't support immersive mode by reflection");
            }
        } else
        {
            MyLog.i("ImmersiveModeHelper: supportFullScreenImmersiveMode: not supported on this platform version");
        }
    }
    private Activity mActivity;
    private Runnable mHideSystemUiCallback = new Runnable()
    {
        @Override
        public void run()
        {
            supportFullScreenImmersiveMode();
        }
    };
    private static final int HIDE_SYSTEM_UI_DELAY_MILLI = 0;
}
 
     
     
     
    