How to Draw Over Other Apps in Android?
Last Updated :
23 Jul, 2025
Sometimes we require our app to show some content on the main screen irrespective of the app running in the foreground, this process is known as drawing over other apps. There are many apps that use this functionality to provide maximum features with minimum screen coverage. This also enables the user to do multitasking. For example, the chat bubble of Facebook Messenger, Mobile Over Usage notice of YourHour App, Voice Command of Google, and many more. We can create similar functionality using the WindowManager interface provided by Android SDK.
Android WindowManager
The Android WindowManager is a system service that controls which windows are displayed and how they are arranged on the screen. When you launch or close an app or rotate the screen, it automatically executes window transitions and animations, among other things.
Every activity has its own Window that displays its content on the screen. When you execute setContentView on an activity, it adds the view to the default window of the activity. Because the default window fills the screen and hides any other activities, the WindowManager will show whatever window is on top. So, in most cases, you don't need to bother about windows; simply build activity, and Android will take care of the rest. In order to manipulate the Window, we need to interact with the window manager. Now in order to display over other apps, we need to create some kind of service, because the activity will close when some other app comes into the foreground.
What we are going to build in this article?
A sample video is given below to get an idea about what we are going to do in this article.
Step by Step Implementation
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.
Note that select Java as the programming language.
Step 2: Working with the AndroidManifest.xml file
In order to draw over other apps we require, android.permission.SYSTEM_ALERT_WINDOW permissions and for android with API version > 23 we need to ask for this on runtime. android.permission.SYSTEM_ALERT_WINDOW allows an app to create windows using the type WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, shown on top of all other apps.
XML
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.raghav.gfgwindowmanager">
<!-- add required permission -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<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/Theme.GFGWindowManager">
<!-- Adding the Service -->
<service
android:name=".ForegroundService"
android:foregroundServiceType="specialUse"
android:enabled="true"
android:exported="false"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Step 3: Working with the activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file.
activity_main.xml:
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
popup_window.xml:
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="4dp"
android:background="@null">
<androidx.cardview.widget.CardView
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="5dp">
<LinearLayout
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/titleText"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Displaying over other apps!"
android:textSize="20sp"
android:textStyle="bold"
android:padding="10dp"/>
<Button
android:id="@+id/window_close"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Remove" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
Step 5: Working with Window.java
Window.java:
Java
package com.raghav.gfgwindowmanager;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Build;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import static android.content.Context.WINDOW_SERVICE;
public class Window {
// declaring required variables
private Context context;
private View mView;
private WindowManager.LayoutParams mParams;
private WindowManager mWindowManager;
private LayoutInflater layoutInflater;
public Window(Context context){
this.context=context;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// set the layout parameters of the window
mParams = new WindowManager.LayoutParams(
// Shrink the window to wrap the content rather
// than filling the screen
WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT,
// Display it on top of other application windows
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
// Don't let it grab the input focus
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// Make the underlying application window visible
// through any transparent parts
PixelFormat.TRANSLUCENT);
}
// getting a LayoutInflater
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// inflating the view with the custom layout we created
mView = layoutInflater.inflate(R.layout.popup_window, null);
// set onClickListener on the remove button, which removes
// the view from the window
mView.findViewById(R.id.window_close).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
close();
}
});
// Define the position of the
// window within the screen
mParams.gravity = Gravity.CENTER;
mWindowManager = (WindowManager)context.getSystemService(WINDOW_SERVICE);
}
public void open() {
try {
// check if the view is already
// inflated or present in the window
if(mView.getWindowToken()==null) {
if(mView.getParent()==null) {
mWindowManager.addView(mView, mParams);
}
}
} catch (Exception e) {
Log.d("Error1",e.toString());
}
}
public void close() {
try {
// remove the view from the window
((WindowManager)context.getSystemService(WINDOW_SERVICE)).removeView(mView);
// invalidate the view
mView.invalidate();
// remove all views
((ViewGroup)mView.getParent()).removeAllViews();
// the above steps are necessary when you are adding and removing
// the view simultaneously, it might give some exceptions
} catch (Exception e) {
Log.d("Error2",e.toString());
}
}
}
Step 6: Creating the ForegroundService class
Java
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
public class ForegroundService extends Service {
public ForegroundService() {
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
// create the custom or default notification
// based on the android version
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
// create an instance of Window class
// and display the content on screen
Window window=new Window(this);
window.open();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
// for android version >=O we need to create
// custom notification stating
// foreground service is running
@RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground()
{
String NOTIFICATION_CHANNEL_ID = "example.permanence";
String channelName = "Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_MIN);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("Service running")
.setContentText("Displaying over other apps")
// this is important, otherwise the notification will show the way
// you want i.e. it will show some default notification
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
}
Step 7: Working with MainActivity.java
Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
MainActivity.java:
Java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkOverlayPermission();
startService();
}
// method for starting the service
public void startService(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// check if the user has already granted
// the Draw over other apps permission
if(Settings.canDrawOverlays(this)) {
// start the service based on the android version
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(new Intent(this, ForegroundService.class));
} else {
startService(new Intent(this, ForegroundService.class));
}
}
}else{
startService(new Intent(this, ForegroundService.class));
}
}
// method to ask user to grant the Overlay permission
public void checkOverlayPermission(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
// send user to the device settings
Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(myIntent);
}
}
}
// check for permission again when user grants it from
// the device settings, and start the service
@Override
protected void onResume() {
super.onResume();
startService();
}
}
Output:
Similar Reads
How to Use SVG Vector Drawables in Android? SVG stands for Scalable Vector Graphics. It is used for rendering two-dimensional images on the internet. SVG is used for high-quality images that can be scaled to any size. we can use SVG files in android too. SVG can be used for icons, for creating images for creating beautiful UI. In this post, w
2 min read
How to Create Text Stickers in Android? Not only a picture is worth a thousand words but also, they are cooler than monotonous text. In this article, we will learn how to create stickers from the TextView. This will be helpful if you are creating an app in which you want to add some text overlay functionality, for example, an image editin
9 min read
How to Use Canvas API in Android Apps? Canvas API is also one of the most used in Android. The name of the API itself tells us that the API is being used for drawing on the drawing board. With the help of this API, we can draw different types of shapes and create custom UI components that are not present in Android. In this article, we w
5 min read
How to Add SlantedTextView in Android App? SlantedTextView is an Android library that allows us to easily create a slanted text in an android app. We can use this feature in many apps such as educational courses app or subscription-based app and in many other apps where some features are available for free and some are paid features. Note th
3 min read
How to Resize a Bitmap in Android? ImageViews are used within the android application to display different types of images. Many times images are displayed within the ImageView using bitmap instead of drawable files. In this article, we will take a look at How to Resize Bitmap in the android application to resize our image to be disp
3 min read
How to Create a Wallpaper App in Android Studio? Almost all Android devices are having a wallpaper set on their home screen. For setting this wallpaper to the screen many Android devices provides a Wallpaper Application where we can browse different types of wallpapers based on various categories. In this article we will look at, building a simila
15+ min read