Android: Pencere eklenemiyor. Bu pencere türü için izin reddedildi


86

Ben bazı bilgi içeren bir pencere görüntülemek için gereken bir uygulama üzerinde çalışıyorum AÇIK telefonun kilidini açmadan Kilitli Ekranda (KeyGuard). Bunu muhtemelen WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG ile yapabileceğimi düşündüm

Ancak, uygulamam aşağıdaki hatayla her çöktüğünde:

android.view.WindowManager $ BadTokenException: android.view.ViewRootImpl$W@40ec8528 pencere eklenemiyor - bu pencere türü için izin reddedildi

Bu gönderilerin ( burada , burada ve burada ) hepsi aynı cevabı veriyor. Manifest dosyasına aşağıdaki izni eklemek için.

android.permission.SYSTEM_ALERT_WINDOW

Uyguladığım çözüm ancak yine de aynı hatayı alıyorum. Neyi yanlış yaptığım hakkında bir fikrin var mı?

Manifest dosyamdaki izinler:

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

Ve bu, Pencereyi kilit ekranına eklemek için kullandığım kod

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

Herhangi bir fikri olan var mı?

PS Android 4.4.2 çalıştıran bir HTC Desire 620 DS üzerinde test ediyorum

Yanıtlar:


31

Tamamen açık olması gereken nedenlerden dolayı, sıradan Uygulamaların kilit ekranının üzerinde rastgele pencereler oluşturmasına izin verilmez . Kilit ekranınızda gerçek kilit ekranını mükemmel bir şekilde taklit edebilecek bir pencere oluştursaydım ne yapabilirdim ki farkı anlayamasaydınız?

Hatanızın teknik nedeni, TYPE_KEYGUARD_DIALOGbayrağın kullanılmasıdır - android.permission.INTERNAL_SYSTEM_WINDOWimza düzeyinde bir izin gerektirir. Bu, yalnızca iznin oluşturucusuyla aynı sertifikayla imzalanan Uygulamaların onu kullanabileceği anlamına gelir.

Oluşturucusu android.permission.INTERNAL_SYSTEM_WINDOWAndroid sisteminin kendisidir, bu nedenle Uygulamanız işletim sisteminin bir parçası olmadığı sürece hiç şansınız olmaz.

Kullanıcıyı kilit ekranından bilgilendirmenin iyi tanımlanmış ve iyi belgelenmiş yolları vardır . Kilit ekranında gösterilen özelleştirilmiş bildirimler oluşturabilirsiniz ve kullanıcı bunlarla etkileşim kurabilir.


2
Şahsen ben Facebook uygulamasının kilit ekranı bildirimleri gibi bir şey arıyordum. Yeni kilit ekranı bildirimlerini zaten biliyordum, ancak bunlar şimdilik yalnızca Android 22'de çalışıyor. Android 16 ve sonraki sürümlerde çalışacak bir çözüme ihtiyacım var. Ama cevabınız çok mantıklı ve ben de öyle kabul edeceğim. Kilit ekranında bir pencere görüntülemeyi başardım ama ihtiyacım olan şey bu değil, aşağıda bulduğum çözümü göndereceğim.
DroidPilot

1
Uygulamalar bu izne ihtiyaç duyarsa, yüklendikten ve açıldıktan sonra verilebilir.
SkorpEN


108

eğer kullanırsan apiLevel >= 19kullanma

WindowManager.LayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 

aşağıdaki hatayı alır:

android.view.WindowManager $ BadTokenException: android.view.ViewRootImpl$W@40ec8528 pencere eklenemiyor - bu pencere türü için izin reddedildi

Bunun yerine şunu kullanın:

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL

3
Ben var ettik TYPE_SYSTEM_ALERTile Android 5.1 üzerinde iyi çalışıyor android.permission.SYSTEM_ALERT_WINDOWmanifest'te verilmiş.
Sam

İle kullanmak android.permission.SYSTEM_ALERT_WINDOWzorunda LayoutParams.TYPE_TOASTmıyım?
t0m

1
LayoutParams.TYPE_TOAST'ı denedim. Benim için Lollipop ve Marshmallow'da hem API seviyesi 6.0.1'de çalışıyor. Bundan önce, yalnızca Lollipop için çalışan WindowManager.LayoutParams.TYPE_SYSTEM_ALERT kullanıyordum.
Prashant

maalesef bazı uygulamaların izin iletişim kutusu istemesi durumunda (görünümünüz etkinse) "Ekran yer paylaşımı algılandı" na neden oluyor
Siarhei

Pencereyi bir hizmet veya yayın alıcısının içinden göstermeye çalışıyorsanız bu işe yaramaz
FindOutIslamNow

80

Sanırım hedefi ayırt etmelisin (Oreo'dan önce ve sonra)

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

Benzer bir teknik kullanmaya çalışıyorum ancak android stüdyosu Build.VERSION_CODES.O& WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY. TargetSdkVersion 26
Gabe O'Leary

Yardımınız için minnettarım +1.
18-18

@ GabeO'Leary Aynı sorunla karşılaşıyorum, bunun için bir çözümünüz var mı?
Sagar

51

Bu sayı için mevcut tüm örnekleri denemek için elimden geleni yaptım. Sonunda bunun cevabını aldım, ne kadar güvenilir olduğunu bilmiyorum ama uygulamam şu anda çökmüyor.

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

Manifest dosyanızda sadece izin verin

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

Buna ek olarak, API seviyesini> = 23 ise kontrol edebilirsiniz.

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

Umarım bir yerlerde birine yardımcı olur. Tam örnek https://anam-android-codes.blogspot.in/?m=1


13

8.0.0 Android API seviyesi için şunu kullanmalısınız:

WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

onun yerine

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL

veya SYSTEM_ALERT.


TYPE_APPLICATION_OVERLAY, Android Studio'da sunulan seçenekler listesinde değil. "Sembol türünü çözemiyorum" mesajı alıyorum. Neyi kaçırıyorum?
philcruz

11

bu kodun mükemmel çalışmasını deneyin

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

hayatımı kurtardın
Fo Nko

Bu kodu oraya koymak için widget'ı göstermek istediğiniz
@BakaWaii

6

Arama

Diğer uygulamaların üzerine çiz

ayarınızda bulun ve uygulamanızı etkinleştirin. Android 8 Oreo için deneyin

Ayarlar> Uygulamalar ve Bildirimler> Uygulama bilgileri> Diğer uygulamaların üzerinde göster> Etkinleştir


1
Sen bir hayat kurtarıcısın
Noor Hossain

5

Öncelikle, manifest dosyasına izninizin olduğundan emin olun.

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

Uygulamanın diğer uygulamalara izin verip vermediğini kontrol edin. Bu izin varsayılan olarak API <23 için mevcuttur. Ancak API> 23 için çalışma zamanında izin istemeniz gerekir.

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

Bu kodu kullanın:

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
xml kodunuzu paylaşabilir ve github'da görüntüleyebilir misiniz veya başka bir şey benim için yararlı olacaktır.
pavel

4

Android O ile uyumlu hale getirmek için projenizde "TYPE_SYSTEM_OVERLAY" bayrağını Windowmanger bayrağını "TYPE_APPLICATION_OVERLAY" olarak değiştirin

WindowManager.LayoutParams.TYPE_PHONE -e WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY


3

Sonunda TYPE_SYSTEM_OVERLAYyerine kullanarak kilit ekranında bir pencere görüntülemeyi başardım TYPE_KEYGUARD_DIALOG. Bu, beklendiği gibi çalışır ve pencereyi kilit ekranına ekler.

Bununla ilgili sorun, pencerenin yapabileceği her şeyin üzerine eklenmiş olmasıdır .Yani, güvenli kilit ekranları olması durumunda, pencere tuş takımınızın / desen kilidinizin üstünde bile görünecektir. Güvenli olmayan bir kilit ekranı olması durumunda, ekranı kilit ekranından açarsanız, bildirim tepsisinin üstünde görünecektir.

Benim için bu kabul edilemez. Umarım bu, bu sorunla karşılaşan herkese yardımcı olabilir.


Çözüm için çok teşekkür ederim. Bunu reddetmenin bir yolu var mı? Diyaloğu olarak eklediğimde kapatamıyorum TYPE_SYSTEM_OVERLAY. AlertDialog'daki setOnDismissListener'ım çağrılmıyor.
Tom Taylor

3

Sadece WindowManageraşağıdaki adımlarla basit bir görünüm ekledim :

  1. Gösterilecek bir düzen dosyası oluştur (benim durumumda dummy_layout)
  2. Bildiride ve dinamik olarak izin ekleyin.
// 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);
}

Bununla WM'ye bir görünüm ekleyebilirsiniz.

Pie'de test edilmiştir.


2

LayoutParams.TYPE_PHONE kullanımdan kaldırıldı. Kodumu bu şekilde güncelledim.

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, api seviyesi 26 veya üstünü gerektirir.


0

İznin reddedilmesinin ana nedeni, başka uygulamalar üzerinde çizim yapma iznimizin olmamasıdır.Aşağıdaki kodla yapılabilecek diğer uygulamalar üzerinde Çizim için izin vermemiz gerekir.

İzin için kod isteyin

    public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;

bunu MainActivity'nize ekleyin


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

Bunu da ekle

    @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

Birlikte çalışma çözüm bulmak için mücadele etti ApplicationContextve TYPE_SYSTEM_ALERTdurumda iletişim herhangi etkinlikten açılmalıdır istiyor ve çözümleri kafa karıştırıcı bulundu bile iletişim kutusudur a kullanımına sahip tekil getApplicationContext()ve isterseniz iletişim olmalıdır TYPE_SYSTEM_ALERTaşağıdaki adımları gerekecektir :

ilk önce doğru temaya sahip diyalog örneğini alın, ayrıca aşağıdaki kod parçamda yaptığım gibi sürüm uyumluluğunu yönetmeniz gerekir:

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

Başlığı, mesajı ve düğmeleri ayarladıktan sonra, iletişim kutusunu şu şekilde oluşturmanız gerekir:

AlertDialog alert = builder.create();

Şimdi typeburada ana ruloyu oynuyor, çökmenin nedeni bu olduğundan, uyumluluğu şu şekilde ele aldım:

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

Not : AppCompatDialogAşağıdaki gibi özel bir iletişim kutusu kullanıyorsanız :

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

tipinizi doğrudan AppCompatDialogaşağıdaki gibi örneğe tanımlayabilirsiniz :

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

Manifest iznini eklemeyi unutmayın:

<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

Kullanımdan WindowManager.LayoutParams.TYPE_SYSTEM_ERRORkaldırıldığı için işletim sistemi sürümü <Oreo için eklendiğinden emin olun .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.