Android: não foi possível adicionar janela. Permissão negada para este tipo de janela

86

Eu estou trabalhando em um aplicativo onde eu preciso para exibir uma janela com algumas informações ON na tela de bloqueio (proteção) sem desbloquear o telefone. Achei que provavelmente poderia fazer isso com WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG

Mas sempre que meu aplicativo trava, ocorre o seguinte erro:

android.view.WindowManager $ BadTokenException: Não é possível adicionar a janela android.view.ViewRootImpl$W@40ec8528 - permissão negada para este tipo de janela

Todas essas postagens ( aqui , aqui e aqui ) dão a mesma resposta. Para adicionar a seguinte permissão no arquivo Manifest.

android.permission.SYSTEM_ALERT_WINDOW

Solução que implementei, mas ainda estou recebendo o mesmo erro. Alguma ideia do que estou fazendo de errado?

Aqui estão as permissões em meu arquivo de manifesto:

<?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" />

E este é o código que uso para adicionar a janela à tela de bloqueio

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

Alguém tem alguma ideia?

PS Estou testando em um HTC Desire 620 DS com Android 4.4.2

DroidPilot
fonte

Respostas:

31

Por razões que deveriam ser completamente óbvias, os aplicativos comuns não têm permissão para criar janelas arbitrárias na parte superior da tela de bloqueio . O que você acha que eu poderia fazer se criasse uma janela em sua tela de bloqueio que pudesse imitar perfeitamente a tela de bloqueio real, de modo que você não pudesse notar a diferença?

O motivo técnico do seu erro é o uso do TYPE_KEYGUARD_DIALOGsinalizador - ele requer android.permission.INTERNAL_SYSTEM_WINDOWuma permissão de nível de assinatura. Isso significa que apenas aplicativos assinados com o mesmo certificado que o criador da permissão podem usá-lo.

O criador do android.permission.INTERNAL_SYSTEM_WINDOWé o próprio sistema Android, portanto, a menos que seu aplicativo faça parte do sistema operacional, você não tem chance.

Existem maneiras bem definidas e bem documentadas de notificar o usuário sobre as informações da tela de bloqueio . Você pode criar notificações personalizadas que são exibidas na tela de bloqueio e o usuário pode interagir com elas.

Adelphus
fonte
2
Pessoalmente, eu estava procurando por algo como as notificações da tela de bloqueio do aplicativo do Facebook. Eu já sabia sobre as novas notificações da tela de bloqueio, mas elas só funcionam no Android 22 por enquanto. Preciso de uma solução que funcione no Android 16 e superior. Mas sua resposta faz todo o sentido e vou aceitá-la como tal. Eu consegui exibir uma janela na tela de bloqueio, mas não é o que eu preciso, postarei a solução que encontrei abaixo.
DroidPilot de
1
Se os aplicativos precisarem dessa permissão, ela pode ser concedida depois de instalada e aberta.
SkorpEN
Acho que, como Oreo, esta é a resposta certa stackoverflow.com/a/48481628/504179
ATom
108

se você usa apiLevel >= 19, não use

WindowManager.LayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 

que obtém o seguinte erro:

android.view.WindowManager $ BadTokenException: Não é possível adicionar a janela android.view.ViewRootImpl$W@40ec8528 - permissão negada para este tipo de janela

Em vez disso, use:

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL
recotone2000
fonte
3
Estou TYPE_SYSTEM_ALERTfuncionando bem no Android 5.1 com o android.permission.SYSTEM_ALERT_WINDOWconcedido no manifesto.
Sam
Eu tenho que usar android.permission.SYSTEM_ALERT_WINDOWcom LayoutParams.TYPE_TOAST?
t0m de
1
Tentei LayoutParams.TYPE_TOAST. Está funcionando para mim no Lollipop e no Marshmallow, ambos API de nível 6.0.1. Antes eu estava usando WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, que estava funcionando apenas para Lollipop.
Prashant
infelizmente, causa “Sobreposição de tela detectada” no caso de algum aplicativo solicitar uma caixa de diálogo de permissão (se sua visualização estiver ativa)
Siarhei
Isso não funcionaria se você estivesse tentando mostrar a janela de um serviço ou receptor de transmissão
FindOutIslamNow
80

Eu acho que você deve diferenciar o alvo (antes e depois do 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
fonte
Estou tentando usar uma técnica semelhante, mas o Android Studio não consegue reconhecer Build.VERSION_CODES.O& WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY. Minha versão alvo é 26
Gabe O'Leary de
Agradeço sua ajuda +1 da minha parte.
Saveen
@ GabeO'Leary Estou enfrentando o mesmo problema, você tem solução para isso?
Sagar
51

Fiz o possível para tentar todos os exemplos disponíveis para esse problema. Finalmente obtive a resposta para isso, não sei o quanto é confiável, mas meu aplicativo não está travando agora.

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

Em seu arquivo de manifesto, apenas dê a permissão

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

Além disso, você também pode verificar o nível da API se for> = 23, então

 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 ajude alguém em algum lugar. Exemplo completo https://anam-android-codes.blogspot.in/?m=1

Anam Ansari
fonte
13

Para o nível de API do Android 8.0.0, você deve usar

WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

ao invés de

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL

ou SYSTEM_ALERT.

Mingquan Liu
fonte
TYPE_APPLICATION_OVERLAY não está na lista de opções apresentada no Android Studio. Recebo "não é possível resolver o tipo de símbolo". o que estou perdendo?
philcruz
11

tente este código funcionando perfeitamente

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
fonte
você salvou minha vida
Fo Nko
@BakaWaii onde você deseja mostrar o widget para colocar esse código funcionará bem
shakirullah orakzai
6

Pesquisa

Desenhar sobre outros aplicativos

em sua configuração e habilite seu aplicativo. Para Android 8 Oreo, tente

Configurações> Aplicativos e notificações> Informações do aplicativo> Sobrepor a outros aplicativos> Ativar

JeffNhan
fonte
1
você é um salva
Noor Hossain
5

Em primeiro lugar, certifique-se de que tem permissão para adicionar no arquivo de manifesto.

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

Verifique se o aplicativo atraiu a permissão de outros aplicativos ou não? Essa permissão está disponível por padrão para API <23. Mas para API> 23, você deve pedir permissão em tempo de execução.

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

Use 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
fonte
1
você pode compartilhar seu código xml e visualizar no github ou qualquer outra coisa que será útil para mim.
pavel
4

mude o sinalizador Windowmanger "TYPE_SYSTEM_OVERLAY" para "TYPE_APPLICATION_OVERLAY" em seu projeto para torná-lo compatível com Android O

WindowManager.LayoutParams.TYPE_PHONE para WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

Rakesh Kumar B Badiger
fonte
3

Eu consegui finalmente exibir uma janela na tela de bloqueio com o uso de em TYPE_SYSTEM_OVERLAYvez de TYPE_KEYGUARD_DIALOG. Isso funciona conforme o esperado e adiciona a janela na tela de bloqueio.

O problema com isso é que a janela é adicionada em cima de tudo o que for possível. Ou seja, a janela aparecerá até na parte superior do seu teclado / bloqueio de padrão no caso de telas de bloqueio seguras. No caso de uma tela de bloqueio desprotegida, ela aparecerá na parte superior da bandeja de notificação se você abri-la na tela de bloqueio.

Para mim, isso é inaceitável. Espero que isso possa ajudar alguém a enfrentar esse problema.

DroidPilot
fonte
Muito obrigado pela solução. Existe uma maneira de descartar isso? Não consigo descartar a caixa de diálogo ao adicioná-la como TYPE_SYSTEM_OVERLAY. Meu setOnDismissListener em AlertDialog não está sendo chamado.
Tom Taylor
3

Acabei de adicionar a visualização simples ao WindowManagercom as seguintes etapas:

  1. Crie um arquivo de layout para mostrar (dummy_layout no meu caso)
  2. Adicione permissão no manifesto e dinamicamente.
// 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);
}

Com isso, você pode adicionar uma visão ao WM.

Testado em Pie.

Radha Krishna
fonte
2

LayoutParams.TYPE_PHONE está obsoleto. Eu atualizei meu código assim.

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 requer nível de API 26 ou superior.

Ashiqul Islam
fonte
0

O principal motivo para a permissão negada é que não temos permissão para desenhar sobre outros aplicativos, temos que fornecer a permissão para desenhar sobre outros aplicativos que pode ser feito pelo seguinte código

Solicitar código para permissão

    public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;

adicione isso em sua 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);
}

Adicione isto também

    @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
fonte
0

Lutei para encontrar a solução de trabalho com ApplicationContexte TYPE_SYSTEM_ALERTencontrei soluções confusas. Caso queira que a caixa de diálogo seja aberta a partir de qualquer atividade, mesmo a caixa de diálogo é um singleton que você deve usar getApplicationContext(), e se quiser que a caixa de diálogo seja, TYPE_SYSTEM_ALERTvocê precisará dos seguintes passos :

primeiro obtenha a instância da caixa de diálogo com o tema correto, também é necessário gerenciar a compatibilidade da versão como fiz no seguinte trecho:

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

Depois de definir o título, a mensagem e os botões, você deve construir o diálogo como:

AlertDialog alert = builder.create();

Agora o typejoga o rolo principal aqui, já que esse é o motivo da falha, tratei a compatibilidade da seguinte maneira:

        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 : se você estiver usando uma caixa de diálogo personalizada AppCompatDialogcomo abaixo:

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

você pode definir diretamente seu tipo para a AppCompatDialoginstância da seguinte maneira:

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

Não se esqueça de adicionar a permissão do manifesto:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
HAXM
fonte
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
fonte
0

Certifique-se de que WindowManager.LayoutParams.TYPE_SYSTEM_ERRORfoi adicionado para a versão do sistema operacional <Oreo, pois está obsoleto.

Jose
fonte