Implement floating apps using WindowManager

Even novice Android developer knows that only foreground app can show and interact with the user and once user switches to another app, the previous one will be paused and hidden. However, what if , for whatever reason, you want develop an app that can always be displayed on top and can be interacted? 


WindowManager will do the job.

Here are the major steps and tricks to get it work properly: 
  • get WindowManager
           mWm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
  • Add your root view as overlay using  WM.addView(), with correct layout parameter
          The trick here is the flags (*note: verify works on 4.3/4.4). Use exactly what I write below, otherwise you won't be able to receive the touch events. Will discuss it in a planed Android-Window-Deep-Dive article. 

           View yourRootView = new YourRootView();
           WindowManager.LayoutParams params = new WindowManager.LayoutParams(w, h,
                 WindowManager.LayoutParams.TYPE_PHONE,   //type                                                      WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH|                  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,   //flag
                 PixelFormat.TRANSLUCENT);                         //format                                                   mWm.addView(yourRootView, params);
  • Specify overlay's position by setting gravity, x and y
          the (xoffset,yOffset) is absolute coordinate the top/left of your overlay view  

              params.gravity = Gravity.TOP | Gravity.LEFT;
              params.x = xOffset;
              params.y = yOffset;
  • Update overlay's position by set new layout parameters (xOffset,yOffset) using updateViewLayout
                mWm.updateViewLayout(yourRootView, params);
  • event handling :  use absolute value   
          The motion event called back (from either onTouch or onTouchEvent ) contains not only relative coordinate but also absolute coordinate. Knowing the later is a life-saver - I had spent long time trying to achieve a smooth
movement using the relative coordinate and finally failed miserably. 

           float x = event.getRawX();
           float y = event.getRawY();

This is short article but contains lots of hard learned tricks and tips. Hope you find it useful. Stay tuned for more about WindowManager - the not that famous but fundamental components in Android GUI framework.  Probably you already know WindowManager is also used when creating a normal Activity, and the view added is called decroView, which containing the status bar and navigation bar.