Skip to main content

Floating Image/Bubble Head on Screen (Android)

 The idea of floating image or bubble head on screen was introduced or say got known or famous through Facebook Messenger application. If you are socially active which I am sure you are, you would have noticed whenever you chat on messenger the chat head appears on screen and is on top of all other apps. You can drag it anywhere on the screen, and ultimately close it. 



My version of the example is little modified from the original idea. The image/bubble head is added first to right-middle-side, as soon as you drag it towards center the bubble gets increased in size. 

So what I am trying to say here is, when in center the bubble is biggest and as it gradually moves to the corners it shrinks. If while dragging, you release it anywhere on the screen it will relocate to possible nearest side. 

Lastly, there is a close button image, when dropped the bubble in there it closes. 

Till now I have only spoken about the working, now lets talk about the code. In Android phones, anything that appears at top of all other apps requires a special permission prior to Lollipop. So to say, since Marshmallow it requires run time permission "Draw over other apps". When enabled you can float a window on Screen on top of all other apps.



 if ((Build.VERSION.SDK_INT >= 23)) {  
           if (!Settings.canDrawOverlays(context)) {  
             Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,  
                 Uri.parse("package:" + getPackageName()));  
             startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);  
           } else if (Settings.canDrawOverlays(context)) {  
             startService(new Intent(context, FloatingCircle.class));  
           }  
         }  
         else  
         {  
           startService(new Intent(context, FloatingCircle.class));  
         }  




The above code asks for permission , when permission given it starts the service of the floating bubble head. 

Next, the service which we are all looking forward to meet and greet. It is really necessary that you know few things about Android Services. Please click link to learn about Services.


 private void initializeView() {  
     windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);  
     windowManagerClose = (WindowManager) getSystemService(WINDOW_SERVICE);  
     smallCircle = new ImageView(this);  
     smallCircle.setImageResource(R.mipmap.dummy);  
     close = new ImageView(this);  
     close.setImageResource(R.mipmap._close);  
     context = FloatingCircle.this;  
     shake = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.wiggle);  
     shake.setRepeatCount(Animation.INFINITE);  
     layout = new LinearLayout(this);  
     layout.addView(close);  
     animator = new MoveAnimator();  
   }  


Method initializeView() initializes all the necessary variables in the code required. Since we have two images to deal with on the Window Manager we require two objects. One is for bubble head and other for close image button. 



 @Override  
   public int onStartCommand(Intent intent, int flags, int startId) {  
     Visibility();  
     _closeParams = new WindowManager.LayoutParams(  
         WindowManager.LayoutParams.WRAP_CONTENT,  
         WindowManager.LayoutParams.WRAP_CONTENT,  
         WindowManager.LayoutParams.TYPE_PHONE,  
         WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,  
         PixelFormat.TRANSLUCENT);  
     _closeParams.gravity = Gravity.BOTTOM | Gravity.CENTER;  
     _closeParams.x = 0;  
     _closeParams.y = 100;  
     myParams = new WindowManager.LayoutParams(  
         (int) (0.18 * screen_width),  
         (int) (0.18 * screen_width),  
         WindowManager.LayoutParams.TYPE_PHONE,  
         WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED  
             | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS  
             | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,  
         PixelFormat.TRANSLUCENT  
     );  
     myParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;  
     myParams.x = screen_width / 2; // horizontal center for the image  
     myParams.y = 0;  
     windowManager.addView(smallCircle, myParams);  
     windowManagerClose.addView(layout, _closeParams);  
     layout.setVisibility(View.INVISIBLE);  
     close.startAnimation(shake);  
     return START_STICKY; //system will try to recreate the service if in case its killed  
   }  


All the actual efforts goes into onStartcommand() method, both the views are added in this method. 


The whole project is available on here.


View my food journey on Zomato!

Comments

  1. hello, i found this article from github answers,

    i have this error

    Unable to add window android.view.ViewRootImpl$W@d6a015 -- permission denied for window type 2002

    even after when i literally copied your java code.

    any leads would be appreciated.

    thank you

    ReplyDelete
  2. Check your manifest file for permission to draw window.

    ReplyDelete
    Replies
    1. i did. the problem is with oreo. when i lower the sdk to 25 it works .. but with 26 it doesnt.

      btw how to turn activity on/off right from notification i mean

      application(button click) > notification set(stays until the app is destroyed) > click on notification(starts the service) > click on notification again (stops the service)

      i am struggling in turning off. please guide.

      Delete
    2. Since you can only stop a service, from the service itself, I recommend you write an interface and when you want to stop the service call the particular method in interface in the service and call stopSelf() method.

      Delete
    3. so i did as you said, and put the stopSelf() in service.java instead of mainactivity.

      thanks to you :D service do stop. with click and longclick, but i wanted to click the notification itself to stop it, and i dont want to .addAction on notification (because it says it is depreciated (sdk23)) and it adds button in notification which i dont want.

      how can i do that?

      Delete
  3. Unable to add window android.view.ViewRootImpl$W@ca0ed1b -- permission denied for window type 2002

    ReplyDelete

Post a Comment