170 votes

Comment empêcher Android de faire une capture d'écran lorsque mon application passe en arrière-plan ?

L'application que je suis en train de créer doit empêcher le système d'exploitation de faire une capture d'écran de l'application lorsqu'elle est mise en arrière-plan pour des raisons de sécurité. De cette façon, l'application ne pourra pas voir le dernier écran actif lorsqu'elle passe d'une application à l'autre.

J'ai l'intention de placer cette fonctionnalité dans la méthode onPause de la classe d'application, mais je dois d'abord trouver comment réaliser cette fonctionnalité.

Y a-t-il quelqu'un qui a une idée de la façon de réparer ce problème ?

301voto

CommonsWare Points 402670

Essayez FLAG_SECURE :

public class FlagSecureTestActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
                         WindowManager.LayoutParams.FLAG_SECURE);

    setContentView(R.layout.main);
  }
}

Cela permet de se prémunir contre les captures d'écran manuelles et les captures d'écran automatiques à partir de l'historique des tâches récentes de l'ICS. Elle permet également de se prémunir contre les enregistrements d'écran (par exemple, les applications utilisant les API de projection de médias).

UPDATE Il s'agit également d'une protection contre Now On Tap ou d'autres assistants sous Android 6.0 ; ils n'auront pas accès aux détails des widgets et des conteneurs de votre interface utilisateur si l'utilisateur fait apparaître l'assistant.

UPDATE #2 Cependant, tout ce qui se trouve dans l'activité ne sera pas protégé. Toute fenêtre pop-up - Dialog , Spinner , AutoCompleteTextView , débordement de la barre d'action, etc. - ne seront pas sécurisés. Vous pouvez corriger le Dialog en appelant getWindow() sur elle et en mettant FLAG_SECURE . Le reste... devient délicat. Voir cet article de blog pour plus.

6 votes

@Dany's : En fait, cela a tout à voir avec la question. Je viens de le tester sur un Nexus S (4.0.3), et cela fonctionne comme prévu : la capture d'écran des tâches récentes est supprimée. Vous voyez toujours le nom et l'icône de l'application, mais la capture d'écran est noire. Vous êtes invités à l'essayer sur du matériel ICS.

0 votes

Merci, je vais y jeter un coup d'œil. Savez-vous si cela fonctionnera également avec le paquet de rétrocompatibilité ?

2 votes

@StingRay5 : FLAG_SECURE existe depuis le début - elle n'avait qu'une signification limitée jusqu'à récemment.

81voto

gardarh Points 905

Faites attention à l'utilisation de WindowManager.LayoutParams.FLAG_SECURE, sur certains appareils (vérifié sur Samsung Galaxy ACE, par exemple GT-S5830) cela rendra la vue brouillée. Cela semble être un bug spécifique à Samsung. Je recommande ce qui suit :

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}

Voici à quoi ressemble un écran brouillé :

Scrambled Screen Image

Cela fonctionne correctement sur les téléphones Samsung ICS, donc je suppose que le problème est isolé aux appareils Gingerbread (ou plus anciens).

9 votes

Vous avez tout à fait raison, nous avons rencontré ce problème, et il était certainement nécessaire de vérifier le niveau de l'API. En fait, j'ai oublié de poster ce message, alors merci de le remettre sur le tapis :)

0 votes

Cela se produit également sur le Samsung Gio (Gingerbread) mais sur Froyo c'est bon - donc cela ne se produit que sur la 2.3.

0 votes

Nous avons également remarqué ce problème. Vous pouvez vérifier dans l'émulateur sur les appareils Gingerbread.

13voto

Davidea Points 1868

La solution fournie par CommonsWare reste valable également dans Lollipop.

Juste une note, si vous voulez continuer à no voir les instantanés dans la liste récente pour le tout le site toutes les activités mises en œuvre doivent être spécifiées dans l'application. onCreate() méthode le drapeau getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); avant setContentView();

Sinon, un instantané dans la liste récente montrera la première activité sans le drapeau si l'utilisateur a navigué à travers celle-ci.

7voto

Gaurav.android Points 24

Si quelqu'un cherche une solution dans laquelle l'application doit être sécurisée (écran superposé) lorsque l'application est en arrière-plan ou en stick de toutes les applications en cours d'exécution et l'application in-app doit permettre la capture d'écran. Essayez ci-dessous:-

@Override
    protected void onResume() {
        super.onResume();
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
    }

    @Override
    protected void onPause() {
        super.onResume();
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    }

3voto

D. Maul Points 173

Voici une solution pour masquer le contenu d'une application en le recouvrant d'un écran splash lorsque l'application est mise en arrière-plan. Cette solution n'utilise pas la technique FLAG_SECURE, je surcharge simplement les méthodes onPause et onResume des écrans et je modifie la vue pour en afficher une qui couvre tout en arrière-plan.

https://stackoverflow.com/a/52976001/6686912

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X