Shortcomings of floating windows on Android

Search for a command to run...

No comments yet. Be the first to comment.
Are you looking for a translation API to use in your new project? We curated a list of the 18 most popular translation service providers’ APIs available on the market. Maybe you’ll find a match! Translating your content online hasn’t ever been easier...

Learn why Spanish is an important language to consider and why it might be one of the first to choose when you start with the localization of your product. There’s no wonder Spanish is the most popular language on our platform! 📖 Introduction Before...

Learn why idioms are difficult to translate correctly, how to identify them in the text, and figure out their meaning to come up with the best translation in this article. Translators know very well that idioms aren't a piece of cake to translate. 🧁...

This short tutorial will help you set up a scalable Nuxt 3 boilerplate for small and large projects. Find out more about the configuration that Localazy uses for their website and build your next project on proven and solid ground. Nuxt 3 is nearing ...

Localazy can take complete care of your translation process with the built-in translation services available inside the platform. Forget the hassle of managing translation projects forever. All you need to do is choose the language and service. Learn...

vaclavhodek's blog
94 posts
Entrepreneur, idea maker, developer, saas & mobile enthusiast. Building developer-friendly localization solution at localazy.com.
Have you ever wondered how to make those floating windows used by Facebook Heads and other apps? Have you ever wanted to use the same technology in your app? It’s easy, and I will guide you through the whole process.
I'm the author of Floating Apps; the first app of its kind on Google Play and the most popular one with over 8 million downloads. After 6 years of the development of the app, I know a bit about it. It’s sometimes tricky, and I spent months reading documentation and Android source code and experimenting. I received feedback from tens of thousands of users and see various issues on different phones with different Android versions.
Here's what I learned along the way.
Before reading this article, it's recommended to go through Floating Windows on Android 8: The Final App.
In this article, I teach you how to overcome some key shortcomings of floating technology.
Below, I write about the most significant shortcomings of floating technology. On some devices, some of the described problems may not appear at all. On other devices, some issues exist, some not.
However, if you want your app to be available to all users, you can't rely on mixed support. Your app would crash frequently, or it wouldn't be usable for a large group of users.
Believe me, I had the privilege to see my app running on thousands of different devices, and I came across weird and illogical bugs and non-standard behavior.
Problem:
The standard Android's AlertDialog needs an underlying activity, and so it's not possible to use it in floating windows - it would cause the app to crash.
Solution:
The best solution is to implement custom dialogs based on floating technology.
In Floating Apps, I implemented many different dialog types:
I also implemented modality. When the dialog is shown, the related window is blocked, and the dialog is brought to the front instead of the window.
Example:
A simple confirmation dialog.

Problem:
With popup menus, there is a similar problem as for AlertDialog. It's not supported in floating windows.
Solution:
As for AlertDialog, I would recommend implementing custom popup menus based on floating technology.
I did for Floating Apps. It relies on popups heavily.
Example:
A simple popup menu shown over its parent window.

Problem:
The copy/paste feature is a real problem. It works well only on a few phones. As a rule of thumb, it's better to consider it unsupported.
Usually, it's possible to highlight/select text. To be more precise, it's possible to select words with a long tap. However, handles used for working with the selection are missing, and therefore, there is no way to select anything else than single words.
And there's another issue. The standard popup with actions (copy, paste, select all, translate, etc.) is somehow connected to the underlying activity on most devices and won’t appear at all.
Solution:
For short texts, it's acceptable to implement OnLongClickListener and use custom popup. However, as it's not possible to select the text this way, it's necessary to introduce Copy all/Cut all functionality. The Facebook Heads uses this solution everywhere. In Floating Apps, I use it too for edit fields.
In Floating Apps, there are mini-apps for notes taking and text editing, and being able to use Copy all only, it wouldn't be a suitable solution. For this reason, these apps use WebView in which a full-size contenteditable div is shown with custom logic for text selection, copying and pasting. It's not perfect, but better than nothing :-).
Example:
A custom copy/paste popup menu.

Problem:
Obtaining permissions from Android M and above requires a dialog to be shown and the method for issuing the request is available in Activity as well as the mechanism for catching the result.
Solution:
In fact, there are two possible solutions to this problem.
In Floating Apps, every single mini-app defines a set of required permissions, and before the app is launched, the service checks whether all permissions are granted. If not, an invisible activity is shown and ask the user to grant missing ones.
Problem:
Some things, such as social logins, requesting SD card access, opening with, sharing, etc., can only be invoked from running activity.
Solution:
I tend to move "configuration" level things to the main app, which is a normal Android app, and once configured, it's usually possible to use them from inside the service.
For Open With / Share With functionality, a hidden activity is a solution both for showing the dialog to open/share with and for receiving data from other apps.
However, you may need to sacrifice functionality that is not supported in the service. For example, I once wanted to implement floating navigation with MapBox, but their SDK expects an instance of Activity to be available. No luck.
Problem:
The most recently added View is rendered on top of all others. There is no mechanism for switching the z-order of Views in WindowManager.
Solution:
In Floating Apps, the switching of floating windows is a complex process.
ImageView is injected to WindowManager with the image of the original window on exactly the same position. In fact, it looks exactly the same as the original window. WindowManager but kept alive.WindowManager, which means that it's effectively brought to the top. ImageView with the rendered image of the window is removed from the WindowManager. Using the approach above, switching windows seems like a seamless process without blinking and other undesired effects.
Of course, in Floating Apps, this is automated, and there is a complex logic around this that also controls the current z-order of all windows and intelligently decides when the switching is necessary and when not.
However, removing and re-adding the window may cause a problem with components rendering content directly to the video memory such as SurfaceView, VideoView, etc. For this reason, Floating Apps automatically disable this process for windows of a certain type.
WebView works well in floating windows, and it's mostly possible to reimplement its interactions such as uploading and downloading files, invalid certificate notifications, requests for location permission, etc. to use floating windows/dialogs described above.
However, there are a few actions that may lead to crashes or are unsupported. I hope I listed all the key issues.
Android tries to offer available apps, aka Open With feature, when opening links with an unknown protocol. As there is no activity, it may cause crashes. However, this behavior can be easily overridden.
The problem with copy/paste described above also exists for WebView, and it's even worse.
It's possible to use WebView to implement a workaround for unsupported text selection because we have full control over the code. However, for other websites, the situation is much complicated.
However, it's possible to get the selected text in the WebView using something like:
webView.loadUrl("javascript:process(window.getSelection().toString());")
And paste the text to WebView using simulating key strokes with dispatchKeyEvent.
Long-clicks may lead to crashes depending on the implementation, and certainly, it's not possible to invoke standard actions like Open In New Window, Download Image, etc.
The solution is to set custom OnLongClickListener for the WebView and get use webView.getHitTestResult() to get information about the clicked element.
Don't forget to return false when webView.getHitTestResult() returns null to let the WebView process the long click correctly, e.g. for selecting texts.
HTML element <select> shows a dialog with available options and cause your app to crash. It's a big deal, and the only solution is to hook the element, override its action, and show custom UI based on floating technology.
It's not a simple task and needs a lot of testing. Don't forget that options in <select> may be nested and disabled.
You learned how to implement floating windows for your app. It's a powerful technology, but it comes with its price.
Use it wisely where it makes sense and try to avoid situations in which you get to shortcomings mentioned in this article and some others I forgot. It's not a simple task to correctly implement all the workarounds to be reliable across different phones and Android versions.
Enjoy it and feel free to share your apps with me.
Also, I will be glad if you decide to localize your apps with Localazy. I put the very same love into it as I did with Floating Apps.
Continue to the last article with tips & tricks I learned the hard way.
This article is part of the Floating Windows on Android series.