Android: permission denied for window type 2038 using TYPE_APPLICATION_OVERLAY

前端 未结 6 1570
礼貌的吻别
礼貌的吻别 2020-12-10 02:28

I trying to create a view that is above other applications:

WindowManager.LayoutParams paramsDirectorView = new WindowManager.LayoutParams(
        WindowMan         


        
相关标签:
6条回答
  • 2020-12-10 02:42
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        }else {
            layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        }
    
    0 讨论(0)
  • 2020-12-10 02:50
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    

    I had the exactly same issue in service class(before and after Marshmallow).

    if (Build.VERSION.SDK_INT >= 23) {
        if (!Settings.canDrawOverlays(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
              Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, 1234);
        }
    } else {
        startService(new Intent(SplashActivity.this,                     
        CheckServicesForApps.class));
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1234) {
                startService(new Intent(SplashActivity.this, 
                CheckServicesForApps.class));
    
        }
    }
    
    public class CheckServicesForApps extends Service {
        private Context context = null;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            ImageView imageView = new ImageView(context);
            imageView.setVisibility(View.GONE);
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                try {
                    windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
    
                    //here is all the science of params
                    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                            WindowManager.LayoutParams.WRAP_CONTENT,
                            WindowManager.LayoutParams.WRAP_CONTENT,
                            WindowManager. LayoutParams.TYPE_SYSTEM_ERROR,
                            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                            PixelFormat.TRANSLUCENT
                    );
    
                    windowManager.addView(imageView, params);
                    hand=new Handler();
    
                } catch (Exception e) {
                    hand=new Handler();
                    e.printStackTrace();
                }
            }else{
                windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    
                final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                        WindowManager.LayoutParams.WRAP_CONTENT,
                        WindowManager.LayoutParams.WRAP_CONTENT,
                        WindowManager.LayoutParams.TYPE_PHONE,
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                        PixelFormat.TRANSLUCENT);
    
                params.gravity = Gravity.TOP | Gravity.CENTER;
                params.x = ((getApplicationContext().getResources().getDisplayMetrics().widthPixels) / 2);
                params.y = ((getApplicationContext().getResources().getDisplayMetrics().heightPixels) / 2);
                windowManager.addView(imageView, params);
            }
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            /* We want this service to continue running until it is explicitly
            * stopped, so return sticky.
            */
            return START_STICKY;
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
    
            if (imageView != null) {
                try {
                    windowManager.removeView(imageView);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            /**** added to fix the bug of view not attached to window manager ****/
        }
    }
    
    0 讨论(0)
  • 2020-12-10 02:52

    Try to change WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY to WindowManager.LayoutParams.TYPE_PHONE?

    0 讨论(0)
  • 2020-12-10 02:53

    Source SYSTEM_ALERT_WINDOW String SYSTEM_ALERT_WINDOW Allows an app to create windows using the type TYPE_APPLICATION_OVERLAY, shown on top of all other apps. Very few apps should use this permission; these windows are intended for system-level interaction with the user.

    Note: If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen. The app requests the user's approval by sending an intent with action ACTION_MANAGE_OVERLAY_PERMISSION. The app can check whether it has this authorization by calling Settings.canDrawOverlays().

    0 讨论(0)
  • 2020-12-10 02:57

    Did you request runtime permission by calling following intent?

    private void requestOverlayPermission() {
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
            return;
        }
    
        Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
        myIntent.setData(Uri.parse("package:" + getPackageName()));
        startActivityForResult(myIntent, APP_PERMISSIONS);
    }
    

    Then in onActivityResult() check if Settings.canDrawOverlays(this) is true otherwise request permission again by calling above method.

    0 讨论(0)
  • 2020-12-10 03:03

    I had the exactly same issue. I guess you should differentiate the target (before and after 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);
    
    0 讨论(0)
提交回复
热议问题