2012-03-22 18 views
120

La aplicación que estoy construyendo tiene el requisito de que la aplicación tenga que evitar que el sistema operativo tome una captura de pantalla de la aplicación cuando se la empuja hacia el fondo por razones de seguridad. De esta forma, no podrá ver la última pantalla activa al cambiar de una aplicación a otra.¿Cómo evito que Android tome una captura de pantalla cuando mi aplicación pasa al segundo plano?

Planeo poner esta funcionalidad en el método onPause de la clase de aplicación, pero primero necesito descubrir cómo puedo lograr esta funcionalidad.

Entonces, ¿hay alguien por ahí que tenga una pista de cómo solucionarlo?

Respuesta

210

Trate 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); 
    } 
} 

Esto definitivamente asegura contra las capturas manuales y capturas de pantalla automáticas de los ICS historia reciente-tareas.

ACTUALIZACIÓN: también se protege contra Now On Tap u otros asistentes en Android 6.0; no tendrán acceso a los detalles de widgets y contenedores en su UI si el usuario abre el asistente.

ACTUALIZACIÓN # 2: sin embargo, no todo en la actividad estará protegido. Cualquier ventana emergente — Dialog, Spinner, AutoCompleteTextView, desbordamiento de la barra de acciones, etc. — será inseguro. Puede solucionar el problema Dialog llamando al getWindow() y configurando FLAG_SECURE. El resto ... se vuelve complicado. Ver this blog post para más.

+5

@ Dany's: En realidad, tiene todo que ver con la pregunta. Acabo de probarlo en un Nexus S (4.0.3), y funciona como se esperaba: se suprime la captura de pantalla de tareas recientes. Todavía ve el nombre y el icono de la aplicación, pero la captura de pantalla es negra. Le invitamos a probarlo en el hardware de ICS. – CommonsWare

+0

Gracias, echaremos un vistazo, ¿alguna idea si esto también funcionará con el paquete de compatibilidad con versiones anteriores? – StingRay5

+2

@ StingRay5: 'FLAG_SECURE' existe desde el principio; solo tiene un significado limitado hasta hace poco. – CommonsWare

69

Tenga cuidado al usar WindowManager.LayoutParams.FLAG_SECURE, en algunos dispositivos (verificado en Samsung Galaxy ACE, por ejemplo, GT-S5830), esto hará que la vista esté codificada. Parece un error específico de Samsung. Yo recomiendo lo siguiente:

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

Esto es lo que se ve como una pantalla revueltos:

Scrambled Screen Image

Esto funciona correctamente en los teléfonos Samsung ICS sin embargo, así que estoy asumiendo problema está aislado de pan de jengibre dispositivos (o más antiguos).

+6

Tiene toda la razón, nos encontramos con este problema, y ​​ciertamente fue necesario para verificar el nivel de la API. En realidad, olvidé publicar esto, así que gracias por traerlo de nuevo. :) – StingRay5

+0

También ocurre en Samsung Gio (Gingerbread) pero en Froyo está bien, por lo que ocurre solo en 2.3 – pixel

+0

También notamos este problema. Puede verificar en el emulador en dispositivos Gingerbread. – twaddington

14

La solución provista por CommonsWare continúa siendo válida también en Lollipop.

Sólo una nota, si quiere seguir no ver instantáneas en la lista reciente para el toda aplicación, todas las actividades implementadas deben especificar en el método onCreate() la bandera getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); antes setContentView();

lo contrario una instantánea en la lista reciente mostrará la primera actividad sin la bandera si el usuario navegó a través de ella.

+1

En mi aplicación, tengo la funcionalidad de configuración/borrado FLAG_SECURE según las preferencias del usuario. Funcionó bien hasta que KITKAT y la pantalla negra se pueden ver en el selector de tareas. En Lollipop, la Vista general muestra la última instantánea de mi aplicación, la hora en que FLAG_SECURE no se configuró (borró). –

+0

@ r.bhardwaj Creo que no podemos hacer tanto en ese caso, pero puede avisar al usuario que el cambio necesita que la aplicación se reinicie para que tenga pleno efecto ;-) y listo. – Davidea

+1

¿Alguien encontró una manera de inflar una vista personalizada antes de que se tome una instantánea para que no sea solo una pantalla negra? Intenté inflar una vista en Window Manager en onPause, pero parece que ya es demasiado tarde. – user1064249

Cuestiones relacionadas