Android: no se puede agregar una ventana. Permiso denegado para este tipo de ventana

85

Estoy trabajando en una aplicación donde necesito para mostrar una ventana con algo de información EN la pantalla de bloqueo (bloqueo de teclas) sin desbloquear el teléfono. Pensé que probablemente podría hacerlo con WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG

Pero cada vez que mi aplicación falla con el siguiente error:

android.view.WindowManager $ BadTokenException: no se puede agregar la ventana android.view.ViewRootImpl$W@40ec8528 - permiso denegado para este tipo de ventana

Todas estas publicaciones ( aquí , aquí y aquí ) dan la misma respuesta. Para agregar el siguiente permiso en el archivo de manifiesto.

android.permission.SYSTEM_ALERT_WINDOW

Solución que he implementado pero sigo recibiendo el mismo error. ¿Alguna idea de lo que estoy haciendo mal?

Estos son los permisos en mi archivo de manifiesto:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.droidpilot.keyguardwindow" >

<uses-sdk
    android:minSdkVersion="16"
    android:targetSdkVersion="21" />

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />

Y este es el código que utilizo para agregar la ventana a la pantalla de bloqueo

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    mView = mInflater.inflate(R.layout.lock_screen_notif, null);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
            PixelFormat.TRANSLUCENT
    );

    wm.addView(mView, params);

¿Alguien tiene alguna idea?

PD: Estoy probando en un HTC Desire 620 DS con Android 4.4.2

DroidPilot
fuente

Respuestas:

30

Por razones que deberían ser completamente obvias, las aplicaciones comunes no pueden crear ventanas arbitrarias en la parte superior de la pantalla de bloqueo . ¿Qué crees que podría hacer si creara una ventana en tu pantalla de bloqueo que pudiera imitar perfectamente la pantalla de bloqueo real para que no pudieras notar la diferencia?

La razón técnica de su error es el uso de la TYPE_KEYGUARD_DIALOGbandera: requiere android.permission.INTERNAL_SYSTEM_WINDOWun permiso de nivel de firma. Esto significa que solo las aplicaciones firmadas con el mismo certificado que el creador del permiso pueden usarlo.

El creador de android.permission.INTERNAL_SYSTEM_WINDOWes el propio sistema Android, por lo que a menos que su aplicación sea parte del sistema operativo, no tiene ninguna posibilidad.

Existen formas bien definidas y bien documentadas de notificar al usuario de la información de la pantalla de bloqueo . Puede crear notificaciones personalizadas que se muestran en la pantalla de bloqueo y el usuario puede interactuar con ellas.

adelfo
fuente
2
Personalmente, estaba buscando algo como las notificaciones de la pantalla de bloqueo de la aplicación de Facebook. Ya conocía las nuevas notificaciones de la pantalla de bloqueo, pero por ahora solo funcionan en Android 22. Necesito una solución que funcione en Android 16 en adelante. Pero tu respuesta tiene mucho sentido y la aceptaré como tal. Sin embargo, logré mostrar una ventana en la pantalla de bloqueo, pero no es lo que necesito, publicaré la solución que encontré a continuación.
DroidPilot
1
Si las aplicaciones necesitan ese permiso, se puede otorgar después de instalarlo y abrirlo.
SkorpEN
Creo que, dado que Oreo, esta es la respuesta correcta stackoverflow.com/a/48481628/504179
ATom
107

si lo usa apiLevel >= 19, no lo use

WindowManager.LayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 

que obtiene el siguiente error:

android.view.WindowManager $ BadTokenException: no se puede agregar la ventana android.view.ViewRootImpl$W@40ec8528 - permiso denegado para este tipo de ventana

Use esto en su lugar:

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL
recotone2000
fuente
3
Trabajé TYPE_SYSTEM_ALERTbien en Android 5.1 con lo android.permission.SYSTEM_ALERT_WINDOWconcedido en el manifiesto.
Sam
Tengo que usar android.permission.SYSTEM_ALERT_WINDOWcon LayoutParams.TYPE_TOAST?
t0m
1
Probé LayoutParams.TYPE_TOAST. Funciona para mí en Lollipop y Marshmallow, ambos niveles de API 6.0.1. Antes de eso, estaba usando WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, que funcionaba solo para Lollipop.
Prashant
desafortunadamente, causa "Superposición de pantalla detectada" en caso de que alguna aplicación solicite un diálogo de permiso (si su vista está activa)
Siarhei
Esto no funcionaría si está intentando mostrar la ventana desde un servicio o receptor de transmisión
FindOutIslamNow
78

Supongo que deberías diferenciar el objetivo (antes y después de Oreo)

int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}

params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    LAYOUT_FLAG,
    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    PixelFormat.TRANSLUCENT);
Cédric Dufouil
fuente
Estoy tratando de usar una técnica similar pero Android Studio no puede reconocer Build.VERSION_CODES.O& WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY. Mi targetSdkVersion es 26
Gabe O'Leary
Agradezco tu ayuda +1 de mi lado.
Saveen
@ GabeO'Leary Estoy enfrentando el mismo problema, ¿tiene una solución para esto?
Sagar
49

Hice todo lo posible para probar todos los ejemplos disponibles para este problema. Finalmente obtuve la respuesta para esto, no sé cuánto es confiable, pero mi aplicación no falla ahora.

windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
    //here is all the science of params
    final LayoutParams myParams = new LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            LayoutParams.TYPE_SYSTEM_ERROR,
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
            PixelFormat.TRANSLUCENT
    );

En su archivo de manifiesto, simplemente dé el permiso

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

Además de esto, también puede verificar el nivel de API si es> = 23 entonces

 if(Build.VERSION.SDK_INT >= 23) {
    if (!Settings.canDrawOverlays(Activity.this)) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, 1234);
    }
}
            else
{
    Intent intent = new Intent(Activity.this, Service.class);
    startService(intent);
}

Espero que ayude a alguien en alguna parte. Ejemplo completo https://anam-android-codes.blogspot.in/?m=1

Anam Ansari
fuente
13

Para el nivel de API de Android 8.0.0, debe usar

WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

en vez de

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL

o SYSTEM_ALERT.

Mingquan Liu
fuente
TYPE_APPLICATION_OVERLAY no está en la lista de opciones presentadas en Android Studio. Recibo "no se puede resolver el tipo de símbolo". ¿Qué me estoy perdiendo?
philcruz
11

prueba este código funcionando perfectamente

int layout_parms;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 

    {  
         layout_parms = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

    }

     else {

            layout_parms = WindowManager.LayoutParams.TYPE_PHONE;

    }

    yourparams = new WindowManager.LayoutParams(       
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            layout_parms,
            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);
shakirullah orakzai
fuente
me salvaste la vida
Fo Nko
@BakaWaii donde desea mostrar el widget para poner este código allí funcionará bien
shakirullah orakzai
6

Buscar

Dibujar sobre otras aplicaciones

en su configuración y habilite su aplicación. Para Android 8 Oreo, prueba

Configuración> Aplicaciones y notificaciones> Información de la aplicación> Mostrar sobre otras aplicaciones> Activar

JeffNhan
fuente
1
eres un salvavidas
Noor Hossain
5

En primer lugar, asegúrese de tener permiso para agregar en el archivo de manifiesto.

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

¿Compruebe si la aplicación tiene permiso para dibujar sobre otras aplicaciones o no? Este permiso está disponible de forma predeterminada para API <23. Pero para API> 23, debe solicitar el permiso en tiempo de ejecución.

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {

    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 1);
} 

Utilice este código:

public class ChatHeadService extends Service {

private WindowManager mWindowManager;
private View mChatHeadView;

WindowManager.LayoutParams params;

public ChatHeadService() {
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

    Language language = new Language();
    //Inflate the chat head layout we created
    mChatHeadView = LayoutInflater.from(this).inflate(R.layout.dialog_incoming_call, null);


    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        params.x = 0;
        params.y = 100;
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mChatHeadView, params);

    } else {
        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                PixelFormat.TRANSLUCENT);


        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        params.x = 0;
        params.y = 100;
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mChatHeadView, params);
    }

    TextView tvTitle=mChatHeadView.findViewById(R.id.tvTitle);
    tvTitle.setText("Incoming Call");

    //Set the close button.
    Button btnReject = (Button) mChatHeadView.findViewById(R.id.btnReject);
    btnReject.setText(language.getText(R.string.reject));
    btnReject.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //close the service and remove the chat head from the window
            stopSelf();
        }
    });

    //Drag and move chat head using user's touch action.
    final Button btnAccept = (Button) mChatHeadView.findViewById(R.id.btnAccept);
    btnAccept.setText(language.getText(R.string.accept));


    LinearLayout linearLayoutMain=mChatHeadView.findViewById(R.id.linearLayoutMain);



    linearLayoutMain.setOnTouchListener(new View.OnTouchListener() {
        private int lastAction;
        private int initialX;
        private int initialY;
        private float initialTouchX;
        private float initialTouchY;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:

                    //remember the initial position.
                    initialX = params.x;
                    initialY = params.y;

                    //get the touch location
                    initialTouchX = event.getRawX();
                    initialTouchY = event.getRawY();

                    lastAction = event.getAction();
                    return true;
                case MotionEvent.ACTION_UP:
                    //As we implemented on touch listener with ACTION_MOVE,
                    //we have to check if the previous action was ACTION_DOWN
                    //to identify if the user clicked the view or not.
                    if (lastAction == MotionEvent.ACTION_DOWN) {
                        //Open the chat conversation click.
                        Intent intent = new Intent(ChatHeadService.this, HomeActivity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);

                        //close the service and remove the chat heads
                        stopSelf();
                    }
                    lastAction = event.getAction();
                    return true;
                case MotionEvent.ACTION_MOVE:
                    //Calculate the X and Y coordinates of the view.
                    params.x = initialX + (int) (event.getRawX() - initialTouchX);
                    params.y = initialY + (int) (event.getRawY() - initialTouchY);

                    //Update the layout with new X & Y coordinate
                    mWindowManager.updateViewLayout(mChatHeadView, params);
                    lastAction = event.getAction();
                    return true;
            }
            return false;
        }
    });
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mChatHeadView != null) mWindowManager.removeView(mChatHeadView);
}

}

Abhijeet Sharma
fuente
¿Puedes compartir tu código xml y verlo en github o en otra cosa? Me será útil.
pavel
4

cambie su bandera Windowmanger flag "TYPE_SYSTEM_OVERLAY" a "TYPE_APPLICATION_OVERLAY" en su proyecto para que sea compatible con Android O

WindowManager.LayoutParams.TYPE_PHONE a WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

Rakesh Kumar B Badiger
fuente
3

Me las arreglé para mostrar finalmente una ventana en la pantalla de bloqueo con el uso de en TYPE_SYSTEM_OVERLAYlugar de TYPE_KEYGUARD_DIALOG. Esto funciona como se esperaba y agrega la ventana a la pantalla de bloqueo.

El problema con esto es que la ventana se agrega encima de todo lo posible. Es decir, la ventana incluso aparecerá en la parte superior de su teclado / patrón de bloqueo en caso de pantallas de bloqueo seguras. En el caso de una pantalla de bloqueo no segura, aparecerá en la parte superior de la bandeja de notificaciones si la abre desde la pantalla de bloqueo.

Para mí, eso es inaceptable. Espero que esto pueda ayudar a cualquier otra persona que se enfrente a este problema.

DroidPilot
fuente
Muchas gracias por la solución. ¿Hay alguna forma de descartarlo? No puedo descartar el diálogo cuando lo agrego como TYPE_SYSTEM_OVERLAY. Mi setOnDismissListener en AlertDialog no se invoca.
Tom Taylor
3

Acabo de agregar una vista simple WindowManagercon los siguientes pasos:

  1. Crear un archivo de diseño para mostrar (dummy_layout en mi caso)
  2. Agregue permiso en manifiesto y de forma dinámica.
// 1. Show view
private void showCustomPopupMenu()
{
    windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
    // LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // View view = layoutInflater.inflate(R.layout.dummy_layout, null);
    ViewGroup valetModeWindow = (ViewGroup) View.inflate(this, R.layout.dummy_layout, null);
    int LAYOUT_FLAG;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
    } else {
        LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
    }
    WindowManager.LayoutParams params=new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        LAYOUT_FLAG,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

    params.gravity= Gravity.CENTER|Gravity.CENTER;
    params.x=0;
    params.y=0;
    windowManager.addView(valetModeWindow, params);
}

// 2. Get permissions by asking
if (!Settings.canDrawOverlays(this)) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 1234);
}

Con esto puede agregar una vista a WM.

Probado en Pie.

Radha Krishna
fuente
2

LayoutParams.TYPE_PHONE está obsoleto. He actualizado mi código como estos.

parameters = if (Build.VERSION.SDK_INT > 25) {
        LayoutParams(
                minHW * 2 / 3, minHW * 2 / 3,
                LayoutParams.TYPE_APPLICATION_OVERLAY,
                LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT)
    }else {
        LayoutParams(
                minHW * 2 / 3, minHW * 2 / 3,
                LayoutParams.TYPE_PHONE,
                LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT)
    }

LayoutParams.TYPE_APPLICATION_OVERLAY requiere API nivel 26 o superior.

Islam Ashiqul
fuente
0

La razón principal para denegar el permiso es que no tenemos permiso para dibujar sobre otras aplicaciones, tenemos que proporcionar el permiso para dibujar sobre otras aplicaciones que se pueden hacer con el siguiente código

Solicitar código de permiso

    public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;

agregue esto en su MainActivity


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
            askPermission();
}


private void askPermission() {
        Intent intent= new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:"+getPackageName()));
        startActivityForResult(intent,ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}

Agrega esto también

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE){
            if(!Settings.canDrawOverlays(this)){
                askPermission();
            }
        }
    }

sai Pavan Kumar
fuente
0

Luché para encontrar la solución de trabajo con ApplicationContexty TYPE_SYSTEM_ALERTencontré soluciones confusas, en caso de que desee que el cuadro de diálogo se abra desde cualquier actividad, incluso el cuadro de diálogo es un singleton que debe usar getApplicationContext(), y si lo desea, el cuadro de diálogo debería ser TYPE_SYSTEM_ALERT, necesitará los siguientes pasos :

primero obtenga la instancia de diálogo con el tema correcto, también necesita administrar la compatibilidad de la versión como lo hice en mi siguiente fragmento:

AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext(), R.style.Theme_AppCompat_Light);

Después de configurar el título, el mensaje y los botones, debe crear el cuadro de diálogo como:

AlertDialog alert = builder.create();

Ahora typejuega el papel principal aquí, ya que esta es la razón del bloqueo, manejé la compatibilidad de la siguiente manera:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        alert.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY - 1);

    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    }

Nota : si está utilizando un cuadro de diálogo personalizado con el AppCompatDialogsiguiente:

AppCompatDialog dialog = new AppCompatDialog(getApplicationContext(), R.style.Theme_AppCompat_Light);

puede definir directamente su tipo en la AppCompatDialoginstancia de la siguiente manera:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY - 1);

    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    }

No olvide agregar el permiso de manifiesto:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
HAXM
fuente
0
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.START | Gravity.TOP;
    params.x = left;
    params.y = top;
    windowManager.addView(view, params);

} else {
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            PixelFormat.TRANSLUCENT);


    params.gravity = Gravity.START | Gravity.TOP;
    params.x = left;
    params.y = top;
    windowManager.addView(view, params);
}
Harpreet
fuente
0

Asegúrese de que WindowManager.LayoutParams.TYPE_SYSTEM_ERRORse agregue para la versión del sistema operativo <Oreo, ya que está obsoleto.

Jose
fuente