What APIs are used to draw over other apps (like Facebook's Chat Heads)?
Asked Answered
R

3

233

How does Facebook create the Chat Heads on Android? What is the API to create the floating views on top of all other views?

Randle answered 12/4, 2013 at 16:3 Comment(4)
This app has also "Chat Heads" play.google.com/store/apps/details?id=com.ninja.smsCliftonclim
If you're looking for an example, see github.com/marshallino16/FloatingNotificationToxicology
You can find a demo and a simple library here: github.com/ericbhatti/floaties Using this library you can create floating windows using just 2 lines.Firry
github.com/recruit-lifestyle/FloatingViewDoubly
S
219

This one:

Allows an application to open windows using the type TYPE_SYSTEM_ALERT, shown on top of all other applications. Very few applications should use this permission; these windows are intended for system-level interaction with the user.

Constant Value: "android.permission.SYSTEM_ALERT_WINDOW"

//EDIT: The full code here:

public class ChatHeadService extends Service {

  private WindowManager windowManager;
  private ImageView chatHead;

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

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

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    chatHead = new ImageView(this);
    chatHead.setImageResource(R.drawable.android_head);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_PHONE,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 100;

    windowManager.addView(chatHead, params);
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    if (chatHead != null) windowManager.removeView(chatHead);
  }
}

Don't forget to start the service somehow:

startService(new Intent(context, ChatHeadService.class));

.. And add this service to your Manifest.

Shelba answered 12/4, 2013 at 21:11 Comment(4)
There's more weird stuff, I think. What about handling input outside the "head" as well as dragability? I think you'd at least need FLAG_NOT_TOUCH_MODAL, as well as some clever logic to update the Window attributes (i.e., move it) while you're dragging it.Sexivalent
Thought that it's worth mentioning an SDK I developed for creating floating UI: www.tooleap.comKarney
@HenryChuang how to use this library in my app?Pious
@14bce109 copy ChatHeadService.java to your project, if your targetSDK bigger than 23, you should implement runtimepermission(somebody say that app published to Google Play does not need to request permission "android.permission.SYSTEM_ALERT_WINDOW", you can try it)Miller
M
52

As a rule, Android activities are full screen, conceptually dedicated UIs that take all the interaction. There are a few exceptions to this. For a start, there are popup dialogs that don't fill the screen. Another is the Android toast, which is a non-interactive popup - you can't touch it, and if you try it'll go to whatever's underneath.

You can do your own special UIs too. You can add views directly to the WindowManager, specifying a type flag. Chat Heads probably uses TYPE_PHONE. There are a few similar types, but the purpose is the same: special purpose overlays that can appear over the top of anything else without the parent application apparently being present.

That only gets you so far, though, because of problems with interaction. At first, your overlay will absorb all the interaction, so not only does the head get events, but you block interaction to everything underneath.

You configure this behaviour using the LayoutParams. FLAG_NOT_TOUCH_MODAL means that events outside of your display area go to the underlying UIs. You'll now find it works, but that other bad things still happen, like the back/menu buttons don't get directed to apps, plus no keyboard. To solve that you need FLAG_NOT_FOCUSABLE.

You get a side effect from the non-focusable bit too, which is no nice interactions with your overlay any more, e.g. button presses. You can get some basic touch events though, which you can always do maths on, and that's probably enough for Chat Heads. Just be aware that it leaves you on your own in plenty of areas, like UI animation.

A good overview of the detail, including allowing for selective interaction consumption, can be found in this StackOverflow thread. In particular one of the answer links will eventually take you here, which is a good example project. Note that ICS changed how this works a little, but the threads explain that.

This is all public API stuff, but it doesn't really seem like a mainstream thing that one ought to be doing as a matter of course. The documentation is littered with references to special system app behaviours, and with good reason; what if everyone did it?

Mahmoud answered 15/4, 2013 at 15:41 Comment(2)
Could I block somehow orientation changes for these view? If underlying activity switches orientation, my view also changes his orientation.Moyers
No. The orientation change is device-wide, not just for the activity.Mahmoud
D
7

Springy heads gives spring based behaviour of chat heads out of the box. All you have to define is the drawable for the chat head and the fragment to open once the chat head is clicked. The chat heads collapse when minimized and follow the finger when dragged.

The project includes a demo app which demonstrates all the built in functionality. To use it, you need to add this into your gradle dependencies.

compile 'com.flipkart.springyheads:library:0.9.6'
Demonography answered 29/12, 2015 at 9:7 Comment(2)
@KiranKumar Thank you, The problem with new lib is the permission of Draw over application in Marshmallow VersionOler
this lib only work within the appLocalism

© 2022 - 2024 — McMap. All rights reserved.