Update : Problem is solved.
WARNING : This question Does not have the answer AT ALL which is mentioned above.
The problem is, there should be WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
instead of TYPE_PHONE
.
If you are having the same problem I would suggest to ask for permission in java class as shown in the link mentioned by 0X0nosugar in the comments.
I am running a service which creates a transparent floating window with some information and user can drag and drop it anywhere.
So far, after adding all views, my service Crashed and I got this error.
java.lang.RuntimeException:
Unable to create service afm.dragger.Dragger:
android.view.WindowManager$BadTokenException:
Unable to add window android.view.ViewRootImpl$W@ba63d06 -- permission denied for window type 2002
My minSdkVersion
is 21 and targetSdkVersion
is 27 and I have sdk 27 on my phone.
Here is my AndroidManifest
:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".Dragger"/>
</application>
Here is my Dragger.class
:
@Override
public void onCreate() {
super.onCreate();
WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setBackgroundColor(Color.parseColor("#33FFFFFF"));
LinearLayout.LayoutParams linearParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
linearLayout.setLayoutParams(linearParams);
Button button = new Button(this);
button.setBackground(getResources().getDrawable(R.drawable.button_shape));
button.setTextColor(getResources().getColor(android.R.color.white));
button.setTextSize(14);
button.setText("Stop Service");
ViewGroup.LayoutParams buttonParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
button.setLayoutParams(buttonParams);
linearLayout.addView(button, buttonParams);
final WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams(350, 250, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
windowParams.x = 0;
windowParams.y = 0;
windowParams.gravity = Gravity.START|Gravity.TOP;
manager.addView(linearLayout, windowParams);
linearLayout.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams updatedParams = windowParams;
int x, y;
float touchedX, touchedY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = updatedParams.x;
y = updatedParams.y;
touchedX = event.getRawX();
touchedY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
updatedParams.x = (int) (x + (event.getRawX() - touchedX));
updatedParams.y = (int) (y + (event.getRawY() - touchedY));
manager.updateViewLayout(linearLayout, updatedParams);
default:
break;
}
return false;
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
manager.removeView(linearLayout);
stopSelf();
}
});
}
And finally, here is my MainActivity
:
start.setOnClickListener
is set to :
startService(new Intent(MainActivity.this, Dragger.class));