web-dev-qa-db-fra.com

Qu'est-ce que WindowManager dans Android?

J'ai essayé de le googler et il n'y a pas de réponse directe et/ou claire.

La définition de site Web du développeur n'est pas claire non plus:

L'interface que les applications utilisent pour parler au gestionnaire de fenêtres. Utilisez Context.getSystemService(Context.WINDOW_SERVICE) pour en obtenir un.

Quelqu'un avec un anglais ordinaire de 6e peut-il expliquer ce que c'est?

Et comment puis-je l'utiliser pour créer un objet flottant qui reste via plusieurs activités, même si je suis passé de l'un à l'autre?

59
tony9099

Le Android WindowManager est un service système, qui est responsable de la gestion de la liste des fenêtres ordonnée en z, quelles fenêtres sont visibles et comment elles sont disposées à l'écran. Entre autres, il est automatiquement effectue des transitions et des animations de fenêtre lors de l'ouverture ou de la fermeture d'une application ou de la rotation de l'écran.

Chaque activité a une fenêtre qui est utilisée pour afficher son contenu à l'écran. Lorsque vous appelez setContentView sur une activité, il attache cette vue à la fenêtre par défaut de l'activité. La fenêtre par défaut remplit l'écran, de sorte que la fenêtre de votre activité masque toutes les autres activités - le WindowManager affichera la fenêtre la plus haute. Donc, normalement, vous n'avez pas à vous soucier des fenêtres - vous créez simplement une activité et Android fera le reste pour vous.

Mais vous devez interagir avec le WindowManager si vous voulez faire quelque chose d'inhabituel comme créer des fenêtres flottantes qui ne remplissent pas l'écran. Si vous souhaitez créer une fenêtre flottante visible devant d'autres applications, vous ne pouvez pas utiliser une activité car votre activité s'arrêtera lorsqu'une autre application apparaîtra au premier plan et sa fenêtre sera masquée ou détruite. Au lieu de cela, vous devez afficher une fenêtre à partir d'un service d'arrière-plan. Par exemple:

WindowManager.LayoutParams p = new WindowManager.LayoutParams(
    // Shrink the window to wrap the content rather than filling the screen 
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    // Display it on top of other application windows, but only for the current user
    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
    // Don't let it grab the input focus
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    // Make the underlying application window visible through any transparent parts
    PixelFormat.TRANSLUCENT);

// Define the position of the window within the screen
p.gravity = Gravity.TOP | Gravity.RIGHT;
p.x = 0;
p.y = 100;

WindowManager windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
windowManager.addView(myView, p);

Pour que cela fonctionne, vous devrez ajouter l'autorisation suivante à votre AndroidManifest.xml

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

Pour Android version api> 23, Android.permission.SYSTEM_ALERT_WINDOW besoin de demander l'exécution. De plus, TYPE_SYSTEM_ERROR et quelques types sont déconseillés dans Android api 26. Voici la manière

public void showWindowManager() {
    if (requestPermission()) {
        return;
    }

    WindowManager.LayoutParams p =
            new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    Build.VERSION.SDK_INT > Build.VERSION_CODES.O
                            ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
                            : WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);


    final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    LayoutInflater layoutInflater =
            (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
    final View popupView = layoutInflater.inflate(R.layout.window_manager_layout, null);
    windowManager.addView(popupView, p);

    // dismiss windowManager after 3s
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            windowManager.removeView(popupView);
        }
    }, 3000);
}

@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
        if (Settings.canDrawOverlays(this)) {
            showWindowManager();
        }
    }
}

public boolean requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.canDrawOverlays(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
            return true;
        }
    }
    return false;
}
5
Phan Van Linh

Le gestionnaire de fenêtres organise l'écran et traite ce qui doit aller où et comment les superposer.

Voici un bel exemple open source d'un objet flottant. Exemple d'objet flottant

2
Pete