web-dev-qa-db-fra.com

Comment créer une activité de superposition plein écran toujours supérieure dans Android

J'aimerais pouvoir créer une activité toujours à l'avant de l'écran d'Android . Elle ne devrait recevoir aucune entrée, mais transmettez-la simplement à l'application suivante située en dessous. Quelque chose comme un HUD.

J'ai pu rechercher que je devais définir le type de fenêtre sous-jacent sur TYPE_SYSTEM_ALERT, mais il semble qu'Android ignore mon code. Aucune exception n'a été émise, même si je supprime la permission de manifeste de Android.permission.SYSTEM_ALERT_WINDOW. (il est nécessaire d'utiliser ce type de fenêtre). Lorsque j'ai essayé d'utiliser le type ALERT dans la boîte de dialogue, cela a fonctionné correctement, mais je ne peux pas transformer la boîte de dialogue en entité transparente en plein écran… .. Voici mon code, il manque peut-être quelque chose de simple.

public void onCreate(Bundle savedInstanceState) {       
     super.onCreate(savedInstanceState);        

     requestWindowFeature(Window.FEATURE_NO_TITLE);
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
     getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);             
     getWindow().setBackgroundDrawableResource(Android.R.color.transparent);
     getWindow().setFormat(PixelFormat.TRANSLUCENT);
     setContentView(R.layout.main);
}

Le paramètre translucide doit être activé en externe dans le manifeste xml, sinon il ne fonctionnait pas non plus.

 <item name="Android:windowIsTranslucent">true</item>
19
tmouse
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);

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

ViewGroup mTopView = (ViewGroup) App.inflater.inflate(R.layout.main, null);
getWindow().setAttributes(params);
wm.addView(mTopView, params);
24
tmouse

J'ai trouvé que la réponse acceptée (par la souris) n'a pas tout à fait fonctionné pour moi. Peut-être que cela a fonctionné pour un ancien niveau d'API? J'utilise le niveau 24 de l'API.

Cette réponse particulière avait recommandé:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
    PixelFormat.TRANSLUCENT
);

Cela pose un problème. Les constructeurs existants pour WindowManager.LayoutParams sont les suivants:

 enter image description here

Ainsi, le drapeau WindowManager.LayoutParams.FLAG_FULLSCREEN est utilisé comme un valeur explicite pour int w et int h. Ce n'est pas bien! Les dimensions de votre vue sont définies sur 1024 * 1024 - ainsi, il ne s'agit pas de remplir écran. Et même si vous explicitement définissez la largeur et la hauteur de la présentation en fonction des dimensions du périphérique: elles ne seront pas mises à jour lorsque l'orientation de l'écran change. Nous avons besoin d'une approche différente…


J'ai trouvé que la construction correcte pour une superposition plein écran ressemble à ceci:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // TYPE_SYSTEM_ALERT is denied in apiLevel >=19
    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_FULLSCREEN,
    PixelFormat.TRANSLUCENT
);

Cela signifie que nous ne spécifions plus explicitement ni largeur ni hauteur. La mise en page repose entièrement sur nos drapeaux à la place.

Oui, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN est toujours un indicateur obligatoire; il est nécessaire si vous voulez dessiner sur des décorations telles que la barre d'état.

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY doit être utilisé à la place de TYPE_SYSTEM_ALERT dans les niveaux d'API> = 19. C’est une note que j’ai écrite il ya quelque temps. Malheureusement, j’ai été incapable de trouver une citation permettant de corroborer la raison pour laquelle j’ai pensé que je le pensais.


Notes bonus (si vous lisez ceci, vous essayez probablement de créer une superposition en plein écran):

Votre manifeste aura besoin de ces autorisations (explication ici ):

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

Je crois comprendre que SYSTEM_ALERT_WINDOW est l’autorisation réelle requise, mais que ACTION_MANAGE_OVERLAY_PERMISSION est également nécessaire: il vous permet de demander au moment de l’exécution que l’utilisateur accorde le privilège SYSTEM_ALERT_WINDOW.

Je fournis ici le code source à mon application de niveau 24, une API fonctionnelle, qui crée une superposition en plein écran.

2
Birchlabs

Regarde ça

mentionnez-le dans votre fichier AndroidManifest.xml

<activity Android:name=".MyActivity" Android:theme="@Android:style/Theme.NoTitleBar.Fullscreen" />

si vous voulez rendre votre activité en plein écran et transparente également

regarde ça

<activity Android:name=".MyActivity" Android:theme="@Android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
0
Ravi1187342