Android: impossibile aggiungere la finestra. Autorizzazione negata per questo tipo di finestra


86

Sto lavorando su un app in cui ho bisogno per visualizzare una finestra con alcune informazioni ON il blocco dello schermo (tastiera) senza sbloccare il telefono. Ho pensato che probabilmente avrei potuto farlo con WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG

Ma ogni volta che la mia app si arresta in modo anomalo con il seguente errore:

android.view.WindowManager $ BadTokenException: impossibile aggiungere la finestra android.view.ViewRootImpl$W@40ec8528 - autorizzazione negata per questo tipo di finestra

Questi post ( qui , qui e qui ) danno tutti la stessa risposta. Per aggiungere la seguente autorizzazione nel file Manifest.

android.permission.SYSTEM_ALERT_WINDOW

Soluzione che ho implementato ma ricevo ancora lo stesso errore. Qualche idea di cosa sto facendo di sbagliato?

Ecco le autorizzazioni nel mio file manifest:

<?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 questo è il codice che uso per aggiungere la finestra alla schermata di blocco

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

Qualcuno ha idea?

PS Sto provando su un HTC Desire 620 DS con Android 4.4.2

Risposte:


31

Per ragioni che dovrebbero essere del tutto ovvie, alle app ordinarie non è consentito creare finestre arbitrarie nella parte superiore della schermata di blocco . Cosa pensi che potrei fare se creassi una finestra sulla schermata di blocco che potrebbe imitare perfettamente la schermata di blocco reale in modo che tu non possa capire la differenza?

Il motivo tecnico del tuo errore è l'uso del TYPE_KEYGUARD_DIALOGflag: richiede android.permission.INTERNAL_SYSTEM_WINDOWun'autorizzazione a livello di firma. Ciò significa che solo le app firmate con lo stesso certificato del creatore dell'autorizzazione possono utilizzarlo.

Il creatore di android.permission.INTERNAL_SYSTEM_WINDOWè il sistema Android stesso, quindi a meno che la tua app non faccia parte del sistema operativo, non hai alcuna possibilità.

Esistono modi ben definiti e ben documentati per notificare all'utente le informazioni dalla schermata di blocco . È possibile creare notifiche personalizzate che vengono visualizzate sulla schermata di blocco e l'utente può interagire con esse.


2
Personalmente stavo cercando qualcosa come le notifiche della schermata di blocco dell'app Facebook. Conoscevo già le nuove notifiche della schermata di blocco, ma per ora funzionano solo su Android 22. Ho bisogno di una soluzione che funzioni su Android 16 e versioni successive. Ma la tua risposta ha perfettamente senso e la accetterò come tale. Sono riuscito a visualizzare una finestra sulla schermata di blocco, ma non è quello che mi serve, posterò la soluzione che ho trovato di seguito.
DroidPilot

1
Se le app necessitano di tale autorizzazione, questa potrebbe essere concessa dopo l'installazione e l'apertura.
SkorpEN

Penso che da quando Oreo questa è la giusta risposta stackoverflow.com/a/48481628/504179
Atom

108

se usi apiLevel >= 19, non usare

WindowManager.LayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 

che ottiene il seguente errore:

android.view.WindowManager $ BadTokenException: impossibile aggiungere la finestra android.view.ViewRootImpl$W@40ec8528 - autorizzazione negata per questo tipo di finestra

Usa questo invece:

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL

3
Ho TYPE_SYSTEM_ALERTfunzionato bene su Android 5.1 con la android.permission.SYSTEM_ALERT_WINDOWconcessione nel manifest.
Sam

Devo usare android.permission.SYSTEM_ALERT_WINDOWcon LayoutParams.TYPE_TOAST?
t0m

1
Ho provato LayoutParams.TYPE_TOAST. Funziona per me su Lollipop e Marshmallow, entrambi a livello API 6.0.1. Prima di allora stavo usando WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, che funzionava solo per Lollipop.
Prashant

purtroppo causa "Rilevata sovrapposizione dello schermo" nel caso in cui alcune applicazioni richiedano una finestra di dialogo di autorizzazione (se la visualizzazione è attiva)
Siarhei

Questo non funzionerebbe se stai cercando di mostrare la finestra da un servizio o da un ricevitore di trasmissione
FindOutIslamNow

80

Immagino che dovresti differenziare l'obiettivo (prima e dopo 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);

Sto cercando di utilizzare una tecnica simile ma Android Studio non è in grado di riconoscere Build.VERSION_CODES.O& WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY. Il mio targetSdkVersion è 26
Gabe O'Leary

Apprezzo il tuo aiuto +1 da parte mia.
Saveen

@ GabeO'Leary Sto affrontando lo stesso problema, hai una soluzione per questo?
Sagar

51

Ho fatto del mio meglio per provare tutti gli esempi disponibili per questo problema. Finalmente ho ottenuto la risposta per questo non so quanto sia affidabile ma la mia app non si blocca ora.

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

Nel tuo file manifest basta dare il permesso

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

Oltre a questo puoi anche controllare il livello API se è> = 23 allora

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

Spero che aiuti qualcuno da qualche parte. Esempio completo https://anam-android-codes.blogspot.in/?m=1


13

Per il livello API Android 8.0.0, dovresti usare

WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

invece di

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL

o SYSTEM_ALERT.


TYPE_APPLICATION_OVERLAY non è nell'elenco di opzioni presentate in Android Studio. Ottengo "impossibile risolvere il tipo di simbolo". Cosa mi manca?
philcruz

11

prova questo codice che funziona perfettamente

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

mi hai salvato la vita
Fo Nko,

@BakaWaii dove vuoi mostrare il widget per inserire questo codice funzionerà bene
shakirullah orakzai

6

Ricerca

Disegna su altre app

nella tua impostazione e attiva la tua app. Per Android 8 Oreo, prova

Impostazioni> App e notifiche> Informazioni app> Visualizza su altre app> Abilita


1
sei un salvavita
Noor Hossain

5

Innanzitutto assicurati di avere l'autorizzazione ad aggiungere nel file manifest.

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

Controlla se l'applicazione ha il permesso di disegnare su altre app o no? Questa autorizzazione è disponibile per impostazione predefinita per API <23. Ma per API> 23 devi chiedere il permesso in runtime.

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

Usa questo codice:

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

}


1
puoi condividere il tuo codice xml e visualizzarlo in GitHub o qualcos'altro sarà utile per me.
padiglione

4

cambia il tuo flag Windowmanger flag "TYPE_SYSTEM_OVERLAY" in "TYPE_APPLICATION_OVERLAY" nel tuo progetto per renderlo compatibile con Android O

WindowManager.LayoutParams.TYPE_PHONE per WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY


3

Sono riuscito a visualizzare finalmente una finestra sulla schermata di blocco con l'uso di TYPE_SYSTEM_OVERLAYinvece di TYPE_KEYGUARD_DIALOG. Funziona come previsto e aggiunge la finestra alla schermata di blocco.

Il problema con questo è che la finestra viene aggiunta in cima a tutto ciò che è possibile. Cioè, la finestra apparirà anche sulla parte superiore della tastiera / blocco pattern in caso di schermate di blocco sicure. Nel caso di una schermata di blocco non protetta, apparirà nella parte superiore della barra delle notifiche se la apri dalla schermata di blocco.

Per me questo è inaccettabile. Spero che questo possa aiutare chiunque altro ad affrontare questo problema.


Grazie mille per la soluzione. C'è un modo per ignorarlo? Non riesco a chiudere la finestra di dialogo quando la aggiungo come TYPE_SYSTEM_OVERLAY. Il mio setOnDismissListener su AlertDialog non viene richiamato.
Tom Taylor

3

Ho appena aggiunto la visualizzazione semplice WindowManagercon i seguenti passaggi:

  1. Crea un file di layout da mostrare (dummy_layout nel mio caso)
  2. Aggiungi l'autorizzazione in manifest e in modo dinamico.
// 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 questo puoi aggiungere una vista a WM.

Testato in Pie.


2

LayoutParams.TYPE_PHONE è obsoleto. Ho aggiornato il mio codice in questo modo.

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 richiede api livello 26 o superiore.


0

Il motivo principale per negare l'autorizzazione è che non abbiamo l'autorizzazione per disegnare su altre app, dobbiamo fornire l'autorizzazione per il disegno su altre app che può essere fatto dal seguente codice

Richiedi il codice per l'autorizzazione

    public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;

aggiungilo nel tuo 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);
}

Aggiungi anche questo

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


0

Ho faticato a trovare la soluzione funzionante con ApplicationContexte TYPE_SYSTEM_ALERTe ho trovato soluzioni confuse, nel caso in cui desideri che la finestra di dialogo venga aperta da qualsiasi attività anche la finestra di dialogo è un singleton devi usare getApplicationContext()e se vuoi la finestra di dialogo dovrebbe essereTYPE_SYSTEM_ALERT avrai bisogno dei seguenti passaggi :

prima ottieni l'istanza della finestra di dialogo con il tema corretto, inoltre devi gestire la compatibilità della versione come ho fatto nel mio seguente frammento:

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

Dopo aver impostato il titolo, il messaggio e i pulsanti devi costruire la finestra di dialogo come:

AlertDialog alert = builder.create();

Ora il typeruolo principale qui è riprodotto, poiché questo è il motivo del crash, ho gestito la compatibilità come segue:

        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 stai usando una finestra di dialogo personalizzata con AppCompatDialogquanto segue:

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

puoi definire direttamente il tuo tipo per l' AppCompatDialogistanza come segue:

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

Non dimenticare di aggiungere l'autorizzazione manifest:

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

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

0

Assicurati che WindowManager.LayoutParams.TYPE_SYSTEM_ERRORsia aggiunto per la versione del sistema operativo <Oreo poiché è stato deprecato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.