Skip to content

Chatheads basics

[ | April 14, 2013]

Facebook recently released a new feature in Facebook Messenger: Chatheads.

Sheldon Chathead

I was surprised that chatheads could be drawn on top of any app. Here is a quick explanation of how it works.

No Activity?

At first you may think it’s a trick with a transparent activity. Let’s see:

$ adb shell dumpsys activity
Running activities (most recent first):
  TaskRecord{42b03c38 #2 A U 0}
    Run #0: ActivityRecord{42adf3f8 u0}

No activity! And that’s because Messenger uses a service:

$ adb shell dumpsys activity services
ACTIVITY MANAGER SERVICES (dumpsys activity services)
* ServiceRecord{43242ae0 u0 com.facebook.orca/.chatheads.ChatHeadService}
  intent={act=com.facebook.orca.chatheads.ACTION_HIDE_CHATHEADS cmp=com.facebook.orca/.chatheads.ChatHeadService}
  app=ProcessRecord{42a11228 32622:com.facebook.orca/u0a10126}
  createTime=-9m19s542ms lastActivity=-3m20s499ms
  executingStart=-3m20s499ms restartTime=-9m19s542ms
  startRequested=true stopIfKilled=false callStart=true lastStartId=65


It’s simple: just add a view to a Window.

As you probably know, an Activity has a Window instance. Dialogs also have their own dedicated Window. Even Services can have Window: InputMethodService uses a Window to receive touch events and draw a keyboard on top of another Window, and DreamService is used to create screensavers.


To open a new window in which you will draw the chathead, you need the SYSTEM_ALERT_WINDOW permission.

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.

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

This is what your users will see when installing the app:

Draw Permission

Android Head

Now that you have the right permission, you just need to call WindowManager#addView() with the view and the corresponding layout params:

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() {

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    chatHead = new ImageView(this);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(

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

    windowManager.addView(chatHead, params);

  public void onDestroy() {
    if (chatHead != null) windowManager.removeView(chatHead);

Don’t forget to start the service somehow:

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

Chathead Android

Drag the head

You can now interact with the view. For example, here is a quick hack to drag the Android head around:

chatHead.setOnTouchListener(new View.OnTouchListener() {
  private int initialX;
  private int initialY;
  private float initialTouchX;
  private float initialTouchY;

  @Override public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        initialX = params.x;
        initialY = params.y;
        initialTouchX = event.getRawX();
        initialTouchY = event.getRawY();
        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(chatHead, params);
        return true;
    return false;


Prior to Facebook Chatheads, this trick was already used by some apps. A few examples:

This feature is nice, but remember that with great power comes great responsibility.

Please take care of your user pixels.



Does this imply that Facebook Chatheads (or any application with SYSTEM_ALERT_WINDOW permission) is able to conduct keylogging and take screenshots at arbitrary time?


Great tutorial! Is there a way to display image only in launcher? When some activity is started, the icon should disapear. I thing there may be two ways: 1. parameter for WindowManager 2. detecting running app But I wasnt lucky to find the solution…


Your tutorial is missing the point, that you need to register your service in the Android manifest file under the application tab.