Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@61b864 -- permission denied for window type 2010

I'm trying to make a System Overlay window,which will appear over lockscreen too. I did manage to do so on version-6.0 but It's not working on version-7.0 AND 8.0. At first run,I was transferred to Overlay setting for my app (as expected from Android M & onwards) and I allowed it.But Now it's keep getting crashed as i tried to launch service from app. I tried all things which is related to this issue but nothing helps me to resolve it yet.I'm getting this error every time I tried to launch the service:-

FATAL EXCEPTION: main
Process: com.example.sumuix.lockdown, PID: 5128
java.lang.RuntimeException: Unable to create service com.example.sumuix.lockdown.MyService:android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@61b864 -- permission denied for window type 2010
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3414)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1683)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6540)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@61b864 -- permission denied for window type 2010
at android.view.ViewRootImpl.setView(ViewRootImpl.java:788)
  at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:92)
  at com.example.sumuix.lockdown.MyService.onCreate(MyService.java:64)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3404)
at android.app.ActivityThread.-wrap4(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1683) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
  at android.app.ActivityThread.main(ActivityThread.java:6540) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Here is my code:-(MyService.java)

@Override
public void onCreate() {
    super.onCreate();
            HeadView = LayoutInflater.from(this).inflate(R.layout.overlay_head,null);
    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);
    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 100;
    mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    mWindowManager.addView(HeadView, params);  //I’m getting error here...(MyService.java:64)from error log

    ImageView closeButton = (ImageView) HeadView.findViewById(R.id.close_btn);
    closeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            stopSelf();
        }
    });

    final ImageView chatHeadImage = (ImageView) HeadView.findViewById(R.id.head);
    chatHeadImage.setOnTouchListener(new View.OnTouchListener() {
//Code for OnTouch.
        }
    });
}

My MainActivity , Where I'm calling the above service:- (MyActivity.java)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    back=(Button) findViewById(R.id.jump);
final Intent intentService=new Intent(MainActivity.this, MyService.class);
    if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(MainActivity.this)) {

        //If the draw over permission is not available open the settings screen
        //to grant the permission.
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent,1234);
    }else {
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startService(intentService);
                finish();
            }
        });
    }

}

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     if (requestCode == 1234) {

         //Check if the permission is granted or not.
         if (Build.VERSION.SDK_INT >= 23 && Settings.canDrawOverlays(MainActivity.this)) {
             back.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View view) {
                     startService(new Intent(MainActivity.this, MyService.class));
                     finish();
                 }
             });
         } else { //Permission is not available
             Toast.makeText(this,
                     "Draw over other app permission not available. Closing the application",
                     Toast.LENGTH_SHORT).show();

             finish();
         }
     } else {
         super.onActivityResult(requestCode, resultCode, data);
     }
 }

In manifeast :-

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

MyService Layout XML:-

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/chat_head_root"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:orientation="vertical">

<ImageView
    android:id="@+id/head"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_marginTop="8dp"
    android:background="@android:drawable/ic_menu_info_details"
    tools:ignore="ContentDescription" />

<ImageView
    android:id="@+id/close_btn"
    android:layout_width="26dp"
    android:layout_height="26dp"
    android:layout_marginLeft="40dp"
    android:background="@android:drawable/ic_menu_close_clear_cancel"
    tools:ignore="ContentDescription" />
</RelativeLayout>

I tried pretty much every thing that I find while searching on internet.I just started with Android so,if I'm doing any minor blunder then please let me know it.Thanks in advance.

like image 966
S.M Avatar asked Jul 14 '17 12:07

S.M


1 Answers

For android 8.0, you MUST use WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY. The error overlay, phone overlay and similar are not working anymore.

See more here: https://developer.android.com/about/versions/oreo/android-8.0-changes.html#o-apps

Don't know why you have issues on android 7 though, never had them myself...

Sidenote

Don't use startService anymore if your service is a foreground service, use startForegroundService or the ContextCompat version of it if your service is a foreground service to avoid possible issues if you want to start your overlay service after boot or anywhere else from the background...

like image 182
prom85 Avatar answered Sep 18 '22 06:09

prom85