Mantener la actividad siempre en la parte superior de la pila, o en el foco cuando las aplicaciones desleales lanzar las actividades?

Tengo una actividad de inmersión en pantalla completa que tiene que permanecer en pantalla completa hasta que el usuario salga explícitamente. (Por ejemplo, piensa en algo como ver un video de Youtube a pantalla completa).

Sin embargo, he notado recientemente que un montón de actividades no deseadas lanzamiento puede romper el comportamiento de mi aplicación. Por ejemplo, muchas "aplicaciones gratuitas" sombrías tienden a generar actividades transparentes a pantalla completa y mostrar anuncios, interrumpiendo al usuario inmediatamente. Las pantallas de notificación de "pantalla completa" de determinadas aplicaciones que en realidad son actividades de pantalla completa también interrumpen instantáneamente mi actividad.

¿Hay una manera de evitar estas actividades que roban el foco, o una manera de mantenerlos detrás de mi actividad de la pantalla completa así que no rompe mi modo de la pantalla completa? En otras palabras, ¿cómo puedo mantener mi actividad siempre en la parte superior siempre que alguna aplicación pícara decide lanzar una actividad sobre la mía?

No es necesario cancelarlos, sino "dejarlos atrás por el momento" hasta que el usuario abandone la actividad de pantalla completa.

Un método que viene a la mente sería relanzar mi actividad con FLAG_ACTIVITY_REORDER_TO_FRONT el momento en que pierde el foco, pero que no se verá bonito para el usuario 🙁

Nota: Si desea probarlo usted mismo, he encontrado una aplicación que "simula" estas actividades de pícaro lanzamiento. Descargue esto: https://play.google.com/store/apps/details?id=com.nlucas.popupnotificationslite&hl=es

Cada vez que reciba notificaciones, inicia una actividad transparente a pantalla completa. Trate de ver un video de Youtube y obtener 10 notificaciones de alguien e imaginar lo distracción que sería.

ACTUALIZACIÓN: Hacer esto no parece funcionar:

 @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (!hasFocus) { Intent i = new Intent(getBaseContext(), MainActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); startActivity(i); } 

Puede ejecutar un servicio en segundo plano que comprueba de vez en cuando para mantener su aplicación en la parte superior:

 public class ServiceKeepInApp extends Service { //private static boolean sendHandler = false; KeepInAppHandler taskHandler = new KeepInAppHandler(this); @Override public void onCreate() { super.onCreate(); //sendHandler = true; taskHandler.sendEmptyMessage(0); } @Override public void onDestroy() { super.onDestroy(); //sendHandler = false; taskHandler.removeCallbacksAndMessages(0); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } @Override public IBinder onBind(Intent arg0) { return null; } private static class KeepInAppHandler extends Handler { private final WeakReference<ServiceKeepInApp> mService; private Context context; private boolean sendHandler = false; public KeepInAppHandler(ServiceKeepInApp mService) { this.mService = new WeakReference<ServiceKeepInApp>(mService); this.context = mService; this.sendHandler = true; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); ActivityManager activityManager = (ActivityManager)context.getSystemService(Service.ACTIVITY_SERVICE); if (activityManager.getRecentTasks(2, 0).size() > 0) { if (activityManager.getRecentTasks(2, 0).get(0).id != GlobalVars.taskID) { activityManager.moveTaskToFront(GlobalVars.taskID, 0); } if (sendHandler) { sendEmptyMessageDelayed(0, 1000); } } } } } 

Entonces tenga una clase de singleton:

 public static class GlobalVars { public static int taskID; public static Intent keepInApp; } 

Entonces en su actividad:

 public class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GlobalVars.taskID = getTaskId(); GlobalVars.keepInApp = new Intent(this, ServiceKeepInApp.class); startService(GlobalVars.keepInApp); } } 

Su mejor apuesta es utilizar "pinning de pantalla" (como se presenta aquí , nuevo en Android L). Cualquier otra cosa es un hack o una solución que no será compatible con versiones anteriores.

Para ser contundente, Android no fue realmente diseñado para permitir que una aplicación incondicional y completamente asumir un dispositivo. Android fue diseñado para ser una herramienta para el usuario que responde a sus deseos. Si su deseo es dejar una aplicación, ¿por qué debería hacerlo difícil? Además, si el usuario desea tener aplicaciones sombreadas que inesperado iniciar las actividades, a continuación, así sea. Todo el mundo juega con las mismas reglas establecidas por el sistema.

  • Vista web de Android con el botón Atrás, si no
  • Diálogo selector de número de Android
  • Diálogo personalizado de la ruleta para Android
  • AlertDialog.Builder abre otro AlertDialog.Builder
  • Diálogo personalizado independiente de la versión de la plataforma con el icono, el título y los botones estándar
  • ProgressDialog Actividad de fondo Fade Out Animation
  • No puedo ver el progreso de spinner en ProgressDialog en Lollipop
  • El cierre de ProgressDialog enClick
  • Android: Dialog de progreso no girando
  • Diálogo de progreso de Android
  • Actividad se ha filtrado ventana / diálogo (esto de nuevo!)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.