Android: superposición en la ventana sobre las actividades de una tarea

Quería crear una superposición, como un HUD, que reside en la pantalla durante la pila de actividad de aplicaciones (la tarea de mi aplicación).

Encontré un par de ejemplos usando WindowManager pero no pude averiguar la parametrización para el z-index correcto si usted quiere. O bien debilitar la siguiente actividad sería ir ontop de mi superposición o fuerte la superposición era un sistema de superposición que era visible también cuando la aplicación se trasladó al fondo.

Apunto para mostrar una vista encima de todas las actividades que pertenecen a mi app o tarea (la aplicación sería preferido). Soy consciente de que las aplicaciones y las tareas son dos cosas diferentes en android …

Lo que explícitamente no quiero es usar ventanas de sistema que requieren android.permission.SYSTEM_ALERT_WINDOW

— mi usecase –

Estoy implementando un flujo que incluye una actividad que proporciona un formulario para la entrada del usuario. Que la entrada del usuario tiene que ser procesada de una manera bastante compleja, produciendo un posible resultado de +/- 10 estados. El procesamiento puede tomar hasta 10 minutos y dependiendo del resultado de ese proceso quiero mostrar una vista correspondiente. Mientras se ejecuta el proceso, intento mantener al usuario actualizado pero no puedo permitirle navegar por la aplicación (excepto abortar el proceso). Todos los posibles resultados de la operación de larga duración se presentarán en una actividad diferente.

Soy muy consciente, que hay varios enfoques posibles (por ejemplo, tener una sola actividad). Pero esa decisión ya se ha hecho y está fuera del alcance de esta cuestión. He implementado una solución que utiliza Windows del sistema para mostrar esa superposición pulg Para ocultar la superposición tengo que contar conStart, onStop eventos e interpretar "La aplicación hizo para moverse en segundo plano" y "La aplicación se movió en primer plano". Esto se siente sucio y no estoy satisfecho con esa solución. Prefiero dar un paso atrás y mostrar mi superposición en la parte superior de la actividad de la llamada y al terminar el proceso de ocultarlo y avanzar a la actividad que muestra el resultado.

Una cosa más que intenté es mover una vista de una actividad a otra. Pero esto muestra algún parpadeo e interrupción de mi animación que no me gusta.

Le agradecería que pudiéramos centrarnos en la cuestión de si es posible mostrar una vista en la parte superior de la ventana de aplicación / tarea en lugar de dentro de un sistema o ventana de actividad;)

3 Solutions collect form web for “Android: superposición en la ventana sobre las actividades de una tarea”

Creo que lo siguiente será de su interés. No necesitará android.permission.SYSTEM_ALERT_WINDOW . El código es para la clase Application.

Los comentarios deben ayudarle a entender la lógica. El código debería funcionar desde el primer momento.

 public class YourApplication extends Application { // Popup to show persistent view PopupWindow pw; // View held by Popup LinearLayout ll; @Override public void onCreate() { super.onCreate(); // Register for Activity Lifecyle Callbacks registerActivityLifecycleCallbacks(new YourCallBack()); // Initialize the view ll = new LinearLayout(this); ll.setLayoutParams(new LayoutParams(100, 100)); ll.setBackgroundColor(Color.BLUE); // Initialize popup pw = new PopupWindow(ll, 100, 100); // Set popup's window layout type to TYPE_TOAST Method[] methods = PopupWindow.class.getMethods(); for(Method m: methods){ if(m.getName().equals("setWindowLayoutType")) { try{ m.invoke(pw, WindowManager.LayoutParams.TYPE_TOAST); }catch(Exception e){ e.printStackTrace(); } break; } } } @Override public void onTerminate() { super.onTerminate(); if (pw != null && pw.isShowing()) { pw.dismiss(); } }; private final class YourCallBack implements ActivityLifecycleCallbacks { int numOfRunning = 0; @Override public void onActivityCreated(Activity arg0, Bundle arg1) { } @Override public void onActivityDestroyed(Activity arg0) { } @Override public void onActivityPaused(Activity arg0) { // An activity has been paused // Decrement count, but wait for a certain // period of time, in case another activity // from this application is being launched numOfRunning--; // Delay: 100 ms // If no activity's onResumed() was called, // its safe to assume that the application // has been paused, in which case, dismiss // the popup new Handler().postDelayed(new Runnable() { @Override public void run() { if (numOfRunning == 0) { pw.dismiss(); } } }, 100L); } @Override public void onActivityResumed(Activity arg0) { // If no activities were running, show the popup if (numOfRunning == 0) { pw.showAtLocation(ll, Gravity.BOTTOM, 0, 0); } // Now, one activity is running numOfRunning++; } @Override public void onActivitySaveInstanceState(Activity arg0, Bundle arg1) { } @Override public void onActivityStarted(Activity arg0) { } @Override public void onActivityStopped(Activity arg0) { } }; } 

Usted realmente sólo tiene dos opciones.

1) Puede crear una actividad con el tema de Theme.Dialog. Esto mostrará un popup en la parte superior de su ventana. Puede crear el diálogo para que sea modal-less (puede hacer clic). En mis pruebas rápidas no pude obtener superposición en los bordes de mi pantalla aunque tal vez la modificación del tema arreglaría eso.

MainActivity.java

 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button test = (Button) this.findViewById(R.id.test); test.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ((Button) v).setBackgroundColor(Color.RED); } }); Intent i = new Intent(this, SecondActivity.class); startActivity(i); } } 

SecondActivity.java

 public class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second_main); Window window = getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); window.setGravity(Gravity.BOTTOM); } @Override public void onBackPressed() { //Override to prevent back button from closing the second activity dialog } } 

Manifiesto

  .... <activity android:name="com.example.control.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.control.SecondActivity" android:theme="@android:style/Theme.Dialog" android:label="@string/app_name" > .... </activity> .... 

2) La segunda opción es utilizar SYSTEM_ALERT_WINDOW. Yo prefiero mucho más este método. Usted es correcto que puede ser visible y encima de cada otra aplicación, sin embargo, puede controlar cuando es visible y cuando no lo es. No voy a publicar ningún código fuente, pero te daré un plan general de ataque.

Cuando cree el servicio, vincule a él utilizando una AIDL. De esta manera usted podrá hablar directamente con el servicio para decirle cuándo "ocultar" y "mostrar" la superposición. Hablando de ocultar y mostrar, onPause y onResume se puede utilizar para decirle al servicio que ocultar y mostrar la superposición. Por último, si necesita recibir eventos de clic en su superposición, resultará ser complicado ya que los eventos táctiles no siempre actúan de la forma que usted espera.

Buena suerte.

Espero que esto ayude

 WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.windowAnimations = android.R.style.Animation_Toast; layoutParams.type = WindowManager.LayoutParams.TYPE_TOAST; layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; layoutParams.format = PixelFormat.TRANSLUCENT; LayoutInflater inflater = getLayoutInflater(); View layout = inflater.inflate(R.layout.your_layout, null); windowManager.addView(layout, layoutParams); 
  • Retrasar la llamada a onQueryTextChange () en SearchView.OnQueryTextListener con SearchView
  • Cómo configurar un mapa de bits como fondo para una vista Android API 10-18?
  • ¿Cómo usar la aleta de vista con tres diseños?
  • Cómo obtener la entrada de searchview a textview
  • Restaurar la jerarquía de vista desde el estado guardado no restaura las vistas agregadas programaticamente
  • Android: alinear el centro de la vista con el de otra vista
  • Cómo mostrar / ocultar submenús dentro de NavigationView android
  • View.onMeasure () no se llama
  • Cómo configurar Tint en NavigationView a algunos iconos
  • Android VideoView - Detecta el punto del tiempo en el video
  • ¿Cuál es la forma más rápida de agregar varias vistas a un LinearLayout?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.