Search code examples
androidandroid-serviceandroid-cameraandroid-permissions

Unable to add window - windowmanager permission denied for this window type 2003 or 2006


I'm working on a video recorder app with a background service. I'm getting these errors:

java.lang.RuntimeException: Unable to start service com.example.justbackgroundcamera.BackgroundVideoRecorder@82e8d33 with Intent { cmp=com.example.justbackgroundcamera/.BackgroundVideoRecorder (has extras) }: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@959f86d -- permission denied for window type 2003

Codes:

    windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
    surfaceView = new SurfaceView(this);
    ViewGroup.LayoutParams layoutParams = new WindowManager.LayoutParams(1, 1,
            Build.VERSION.SDK_INT < Build.VERSION_CODES.O ?
                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT :
                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);
    // layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
    windowManager.addView(surfaceView, layoutParams);
    surfaceView.getHolder().addCallback(this);

Manifest:

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

I think there are some errors about permissions. How do I get these permissions?


Solution

  • I've solved the problem. We need some permissions when working with Android M and above. You can fix this problem with "draw over other apps" permission.

    Add to manifest

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

    WindowManager

        windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        surfaceView = new SurfaceView(this);
        ViewGroup.LayoutParams layoutParams = new WindowManager.LayoutParams(1, 1,
                Build.VERSION.SDK_INT < Build.VERSION_CODES.O ?
                        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY :
                        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);
        windowManager.addView(surfaceView, layoutParams);
        surfaceView.getHolder().addCallback(this);
    

    Add to your codes (onCreate)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, 0);
            }
        }