I'd started an Android project, and I need to create a small image button that is always on top of all applications. I have seen some other apps doing that, and I want it to be like those. It should be movable in the screen (for example, like YouTube or Telegram's video overlays) and should be destroyable too.
I also would like to handle the clicks on my image overlay.
So far I've followed some other tutorials and I have granted the Settings.ACTION_MANAGE_OVERLAY_PERMISSION
permission. But I don't know what to do after that.
Any helps would be greatly appreciated
Alright. Heres a piece of code which does the job: (You can change the ImageView to any other thing and use it as an overlay.)
startPowerOverlay()
function:
@SuppressLint("ClickableViewAccessibility")
private void startPowerOverlay(){
// Starts the button overlay.
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
overlayPowerBtn = new ImageView(this);
overlayPowerBtn.setImageResource(R.drawable.REPLACE_ME);
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// APPLICATION_OVERLAY FOR ANDROID 26+ AS THE PREVIOUS VERSION RAISES ERRORS
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
// FOR PREVIOUS VERSIONS USE TYPE_PHONE AS THE NEW VERSION IS NOT SUPPORTED
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.TOP | Gravity.START;
params.x = 0;
params.y = 100;
params.height = 110;
params.width = 110;
windowManager.addView(overlayPowerBtn, params);
overlayPowerBtn.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
private long latestPressTime = 0;
@Override public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Save current x/y
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
// Check for double clicks.
if (latestPressTime == 0 || latestPressTime + 500 < System.currentTimeMillis()) {
latestPressTime = System.currentTimeMillis();
} else {
// Doubleclicked. Do any action you'd like
}
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(overlayPowerBtn, params);
return true;
}
return false;
}
});
}
on onCreate()
:
// Check for overlay permission. If not enabled, request for it. If enabled, show the overlay
if(Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)){
CharSequence text = "Please grant the access to the application.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.fromParts("package", getPackageName(), null)));
} else {
startPowerOverlay();
}
on onDestroy()
:
if (overlayPowerBtn != null)
windowManager.removeView(overlayPowerBtn);
Hope it helps.