web-dev-qa-db-fra.com

Empêcher la barre d'état d'apparaître sous Android (modifié)

Je suis en train d'implémenter une application en mode kiosque et j'ai réussi à la faire en plein écran sans l'apparence de la barre d'état post 4.3 mais impossible de masquer la barre d'état dans les versions 4.3 et 4.4, car la barre d'état apparaît lorsque nous glissons vers le bas en haut de l'écran.

J'ai essayé de le faire en plein écran par

  • en spécifiant le thème plein écran dans le manifeste
  • réglage de la fenêtre Drapeaux ie setFlags
  • setSystemUiVisibility

Double possible mais aucune solution concrète trouvée

Masquer en permanence la barre d'état Android

Enfin, ce que je veux, c'est comment cacher la barre d'état de manière permanente dans une activité? dans Android 4.3,4.4,5,6versions 

25
Abhimaan

Nous n'avons pas pu empêcher le statut d'apparaître en mode plein écran sur les périphériques KitKat. Nous avons donc créé un hack qui convient toujours, c.-à-d. Que la barre d'état ne se développe pas.

Pour que cela fonctionne, l'application n'a pas été rendue en plein écran. Nous plaçons une superposition sur la barre d'état et utilisons tous les événements en entrée. Cela empêchait l'expansion du statut.

Remarque:

  • customViewGroup est une classe personnalisée qui étend toute disposition (cadre, disposition relative, etc.) et utilise un événement tactile. 
  • pour consommer un événement tactile, substituez la méthode onInterceptTouchEvent du groupe de vues .__ et renvoyez true

Mis à jour

<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW"/> 

implémentation customViewGroup

Code:

WindowManager manager = ((WindowManager) getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));

WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

            // this is to enable the notification to recieve touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    localLayoutParams.height = (int) (50 * getResources()
            .getDisplayMetrics().scaledDensity);
    localLayoutParams.format = PixelFormat.TRANSPARENT;

    customViewGroup view = new customViewGroup(this);

    manager.addView(view, localLayoutParams);
85
Abhimaan

Sous Android M, vous devez obtenir une autorisation supplémentaire pour créer des superpositions. Android.permission.SYSTEM_ALERT_WINDOW n'est pas suffisant! J'ai donc utilisé le code de la réponse de Abhimaan dans disableStatusBar() et je devais avoir l'intention d'ouvrir la boîte de dialogue des paramètres appropriés. J'ai également ajouté la suppression de la vue dans onDestroy() afin d'activer la barre d'état lorsque l'application se ferme. J'ai également réduit la hauteur de recouvrement à 40 car cela semble être suffisant. Le code fonctionne avec 5.1 et 6.0 ici.

public static final int OVERLAY_PERMISSION_REQ_CODE = 4545;
protected CustomViewGroup blockingView = null;

@Override
protected void onDestroy() {

    super.onDestroy();

    if (blockingView!=null) {
        WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
        manager.removeView(blockingView);
    }
}


@Override
protected void onCreate(Bundle savedInstanceState) {

        if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            if (!Settings.canDrawOverlays(this)) {
                Toast.makeText(this, "Please give my app this permission!", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
            } else {
                disableStatusBar();
            }
        }
        else {
            disableStatusBar();
        }
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
        if (!Settings.canDrawOverlays(this)) {
            Toast.makeText(this, "User can access system settings without this permission!", Toast.LENGTH_SHORT).show();
        }
        else
        { disableStatusBar();
        }
    }
}

protected void disableStatusBar() {

    WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));

    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
    localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
    localLayoutParams.gravity = Gravity.TOP;
    localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

            // this is to enable the notification to receive touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    localLayoutParams.height = (int) (40 * getResources().getDisplayMetrics().scaledDensity);
    localLayoutParams.format = PixelFormat.TRANSPARENT;

    blockingView = new CustomViewGroup(this);
    manager.addView(blockingView, localLayoutParams);
}
17
Alexey Ozerov

Pour un projet sur lequel j'avais travaillé, j'avais trouvé une solution à ce problème, mais cela prenait beaucoup de temps. Divers fils de discussion sur Stackoverflow et ailleurs m'ont aidé à le trouver. C'était un travail sur Android M mais cela fonctionnait parfaitement. Comme quelqu'un l'a demandé, j'ai donc pensé que je devrais l'afficher ici si cela peut profiter à quiconque.

Maintenant que cela fait longtemps, je ne me souviens pas de tous les détails, mais CustomViewGroup est la classe qui remplace le ViewGroup principal et détecte qu'un utilisateur a balayé le haut pour afficher la barre d'état. Mais nous ne voulions pas le montrer. L’interception de l’utilisateur a donc été détectée et toute action ultérieure a été ignorée, c’est-à-dire que le système d’exploitation Android ne recevra pas de signal lui permettant d’ouvrir la barre d’état masquée.

Et ensuite, les méthodes d'affichage et de masquage de la barre d'état sont également incluses. Vous pouvez les copier/coller telles quelles dans votre code, là où vous souhaitez afficher/masquer la barre d'état.

/**
 * This class creates the overlay on the status bar which stops it from expanding.
 */
public static class CustomViewGroup extends ViewGroup {

    public CustomViewGroup(Context context) {
        super(context);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.v("customViewGroup", "********** Status bar swipe intercepted");
        return true;
    }
}

public static void allowStatusBarExpansion(Context context) {
    CustomViewGroup view = new CustomViewGroup(context);
    WindowManager manager = ((WindowManager) context.getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));
    manager.removeView(view);
}

// Stop expansion of the status bar on swipe down.
public static void preventStatusBarExpansion(Context context) {
    WindowManager manager = ((WindowManager) context.getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));

    Activity activity = (Activity) context;
    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
    localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
    localLayoutParams.gravity = Gravity.TOP;
    localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

            // this is to enable the notification to receive touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    //http://stackoverflow.com/questions/1016896/get-screen-dimensions-in-pixels
    int resId = activity.getResources().getIdentifier("status_bar_height", "dimen", "Android");
    int result = 0;
    if (resId > 0) {
        result = activity.getResources().getDimensionPixelSize(resId);
    }

    localLayoutParams.height = result;

    localLayoutParams.format = PixelFormat.TRANSPARENT;

    CustomViewGroup view = new CustomViewGroup(context);

    manager.addView(view, localLayoutParams);
}
0
zeeshan