Draw Overlay in Android (System Wide)

Draw Overlay in Android (system wide)

It's possible to do that by creating a Service that adds the view in the current WindowManager:

public class OverlayService extends Service {

@Override
public void onCreate() {
super.onCreate();

WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

View overlay = /* create your overlay here */;

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
windowManager.addView(overlay , params);
}

@Override
public IBinder onBind(Intent intent) {
return null;
}
}

But you need this extra permission:

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

And then just register the service in the manifest:

<service android:name=".OverlayService" ></service>

and start it:

startService(new Intent(this, OverlayService.class));

Android: Overlay on Window over Activities of a Task

I think the following will be of interest to you. You won't require android.permission.SYSTEM_ALERT_WINDOW. The code is for the Application class.

Comments should help you understand the logic. The code should work right out of the box.

public class YourApplication extends Application {

// Popup to show persistent view
PopupWindow pw;

// View held by Popup
LinearLayout ll;

@Override
public void onCreate() {
super.onCreate();

// Register for Activity Lifecyle Callbacks
registerActivityLifecycleCallbacks(new YourCallBack());

// Initialize the view
ll = new LinearLayout(this);
ll.setLayoutParams(new LayoutParams(100, 100));
ll.setBackgroundColor(Color.BLUE);

// Initialize popup
pw = new PopupWindow(ll, 100, 100);

// Set popup's window layout type to TYPE_TOAST
Method[] methods = PopupWindow.class.getMethods();
for(Method m: methods){
if(m.getName().equals("setWindowLayoutType")) {
try{
m.invoke(pw, WindowManager.LayoutParams.TYPE_TOAST);
}catch(Exception e){
e.printStackTrace();
}
break;
}
}
}

@Override
public void onTerminate() {
super.onTerminate();

if (pw != null && pw.isShowing()) {
pw.dismiss();
}
};

private final class YourCallBack implements ActivityLifecycleCallbacks {

int numOfRunning = 0;

@Override
public void onActivityCreated(Activity arg0, Bundle arg1) { }

@Override
public void onActivityDestroyed(Activity arg0) { }

@Override
public void onActivityPaused(Activity arg0) {

// An activity has been paused
// Decrement count, but wait for a certain
// period of time, in case another activity
// from this application is being launched
numOfRunning--;

// Delay: 100 ms
// If no activity's onResumed() was called,
// its safe to assume that the application
// has been paused, in which case, dismiss
// the popup
new Handler().postDelayed(new Runnable() {

@Override
public void run() {
if (numOfRunning == 0) {
pw.dismiss();
}
}
}, 100L);
}

@Override
public void onActivityResumed(Activity arg0) {

// If no activities were running, show the popup
if (numOfRunning == 0) {
pw.showAtLocation(ll, Gravity.BOTTOM, 0, 0);
}

// Now, one activity is running
numOfRunning++;
}

@Override
public void onActivitySaveInstanceState(Activity arg0, Bundle arg1) { }

@Override
public void onActivityStarted(Activity arg0) { }

@Override
public void onActivityStopped(Activity arg0) { }

};
}

Android overlay to grab ALL touch, and pass them on?

Found this documentation that pretty much states that it's not possible to do both:
Android : Multi touch and TYPE_SYSTEM_OVERLAY

They discuss workarounds but I don't think any of them will actually work for exactly what I'm trying to do. Both given the events to the underlying app, and being able to snoop them to act upon them for myself.

To create an overlay view, when setting up the LayoutParams you need
to set the type to TYPE_SYSTEM_OVERLAY and use the flag
FLAG_WATCH_OUTSIDE_TOUCH. This presents a problem because as the
Android documentation states: "you will not receive the full
down/move/up gesture, only the location of the first down as an
ACTION_OUTSIDE." In order to receive the full array of touch events
you need to use the TYPE_SYSTEM_ALERT type, but this causes the
overlay to take over the screen and stop interaction with other
elements.

Anyone wants to disagree I'd love to hear good news :-D

Oreo (API 26) - drawOverlay + draw over status bar

The docs says that the flag is deprecated for non-system apps. Have you tried making the app a system app?

This constant was deprecated in API level 26. for non-system apps.

Here is how with ES File Explorer:

Configure ES File Explorer by doing the following steps:
Launch ES File Explorer.
Select Menu and choose Settings.
Under Settings, enable the options for Up to root and Root Explorer. A message will appear, requiring you to confirm your action. You will also need to confirm Superuser access.
Enable Mount File System.
Go back to the app’s main menu.
Get a copy of the APK (Android Package) of the app that you want to save as a system file by doing the following steps (skip to step 3 if you already have the app’s APK file):
Install an app from the Google Play Store. For this guide, we will be using the app BioRhythms as an example.
Launch ES File Explorer and navigate to /data/app.
Locate the APK file that you want to install as a system app. If you don’t know the APK’s filename, simply go to the Google Play Store link of your chosen app. View the link and take note of the words after “?id=”. This will be your APK’s filename. For instance, the BioRhythms app link is https://play.google.com/store/apps/details?id=app.biorhythms. The BioRhythms’ APK is app.biorhythms-1.apk.
Create a backup of the chosen APK by copying it to the phone’s SD Card.
After creating a backup, long tap on the APK file and a menu will appear. Choose Cut. A blue arrow will appear at the bottom of the screen.
Go back to the main menu and navigate to /system/app/.
Drag the little arrow at the bottom of the screen. It will bring up the icon of the APK file.
Tap the APK file and it will be transferred to /system/app/.
Find the APK file in /system/app/. Press and hold it and a menu will appear.
Select Properties on the menu. The dialog properties will show up.
Tap Change and it will show the permissions dialog box.
Check the boxes for the following permissions in the dialog box:
User: Read and Write
Group: Read
Other: Read
Select OK once the required settings have been made.
Reboot your device.


Related Topics



Leave a reply



Submit