Floating widgets are the views that float over the screen. This view will remain floating on the screen no matter whichever screen you are in. They are very convenient for multitasking as a user can work on other application and control your application for the same time. That means if you are in the calculator application and a widget from the music player is floating over the screen, you can control your music at the same time. Pretty cool!

In this tutorial, we are going to learn how to create simple floating widget and allow the user to drag them across the screen. So that user can adjust the position of the floating widget on the screen. We are going to develop a floating view that is having buttons to control the music. (To keep this article focused around floating widget, we will not look into how to control music)

android-facebook-like-floating-chat-head

Final Preview:

android-floating-chat-widget-like-facebook

So, let’s get started.

1. Understanding the basics

Floating widget is nothing but the view that is drawn over other applications. Android system allows applications to draw over other application if the application has android.permission.SYSTEM_ALERT_WINDOW permission. We are going to use the background service to add the floating widget into the view hierarchy of the current screen. So, this floating view is always on top of application windows.

To drag the view across the screen we are going to override OnTouchListener() to listen to drag events and change the position of the view has in the screen.

2. Creating New Project

1. Create a new project in Android Studio from File ⇒ New Project and fill all the necessary details.

2. Download this resource drawables and add them to project’s res directory. This folder contains all the necessary icons & images required for this app.

3. Add android.permission.SYSTEM_ALERT_WINDOW permission to the AndroidManifest.xml file. This permission allows an app to create windows, shown on top of all other apps. We’ll also add a service named FloatingViewService that will be created shortly.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="info.androidhive.floatingview">
    
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name="info.androidhive.floatingview.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service
            android:name="info.androidhive.floatingview.FloatingViewService"
            android:enabled="true"
            android:exported="false"/>
    </application>

</manifest>

4. Create a new layout file named layout_floating_widget.xml for the floating view. This layout will contain two main views.

Collapsed view:
The floating widget will remain collapsed when the view is launched. When the user clicks on this view, an expanded view will open.

Expanded View:
This view will contain buttons to play music, change the song to next/previous and open the application.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <!--Root container-->
    <RelativeLayout
        android:id="@+id/root_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:ignore="UselessParent">

        <!--View while view is collapsed-->
        <RelativeLayout
            android:id="@+id/collapse_view"
            android:layout_width="wrap_content"
            android:visibility="visible"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <!--Icon of floating widget -->
            <ImageView
                android:id="@+id/collapsed_iv"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_marginTop="8dp"
                android:src="@drawable/ic_android_circle"
                tools:ignore="ContentDescription"/>

            <!--Close button-->
            <ImageView
                android:id="@+id/close_btn"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginLeft="40dp"
                android:src="@drawable/ic_close"
                tools:ignore="ContentDescription"/>
        </RelativeLayout>

        <!--View while view is expanded-->
        <LinearLayout
            android:id="@+id/expanded_container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#F8BBD0"
            android:visibility="gone"
            android:orientation="horizontal"
            android:padding="8dp">

            <!--Album image for the song currently playing.-->
            <ImageView
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:src="@drawable/music_player"
                tools:ignore="ContentDescription"/>

            <!--Previous button-->
            <ImageView
                android:id="@+id/prev_btn"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="20dp"
                android:src="@mipmap/ic_previous"
                tools:ignore="ContentDescription"/>

            <!--Play button-->
            <ImageView
                android:id="@+id/play_btn"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="10dp"
                android:src="@mipmap/ic_play"
                tools:ignore="ContentDescription"/>

            <!--Next button-->
            <ImageView
                android:id="@+id/next_btn"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="10dp"
                android:src="@mipmap/ic_play_next"
                tools:ignore="ContentDescription"/>

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <ImageView
                    android:id="@+id/close_button"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:src="@drawable/ic_close"/>

                <ImageView
                    android:id="@+id/open_button"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:layout_alignParentBottom="true"
                    android:src="@drawable/ic_open"/>
            </RelativeLayout>
        </LinearLayout>
    </RelativeLayout>
</FrameLayout>

2.1 Adding Floating Widget (Music Controls) and handle Dragging

Now create a service called FloatingViewService.java. Whenever you want to display a floating view, start the service using startService() command. In onCreate() of the service, we will add the layout of the floating view at the top-left corner of the window.

public class FloatingViewService extends Service {
   private WindowManager mWindowManager;
   private View mFloatingView;

   public FloatingViewService() {
   }

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

   @Override
   public void onCreate() {
       super.onCreate();
       //Inflate the floating view layout we created
       mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);

       //Add the view to the window.
       final 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);

       //Specify the view position
       params.gravity = Gravity.TOP | Gravity.LEFT;        //Initially view will be added to top-left corner
       params.x = 0;
       params.y = 100;

       //Add the view to the window
       mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
       mWindowManager.addView(mFloatingView, params);

       //….
       //….
   }


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

Also, we are implementing OnClickListner() for all the buttons like play, pause, and open application. You can implement a function to play pause music on button click using MediaPlayer. When the user clicks on the close button in the collapsed view, FloatingViewService will get destroyed and floating view will be removed from the view hierarchy.

Add the below code to FloatingViewService.java in onCrate() method.

//The root element of the collapsed view layout
final View collapsedView = mFloatingView.findViewById(R.id.collapse_view);
//The root element of the expanded view layout
final View expandedView = mFloatingView.findViewById(R.id.expanded_container);


//Set the close button
ImageView closeButtonCollapsed = (ImageView) mFloatingView.findViewById(R.id.close_btn);
closeButtonCollapsed.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       //close the service and remove the from from the window
       stopSelf();
   }
});


//Set the view while floating view is expanded.
//Set the play button.
ImageView playButton = (ImageView) mFloatingView.findViewById(R.id.play_btn);
playButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       Toast.makeText(FloatingViewService.this, "Playing the song.", Toast.LENGTH_LONG).show();
   }
});


//Set the next button.
ImageView nextButton = (ImageView) mFloatingView.findViewById(R.id.next_btn);
nextButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       Toast.makeText(FloatingViewService.this, "Playing next song.", Toast.LENGTH_LONG).show();
   }
});


//Set the pause button.
ImageView prevButton = (ImageView) mFloatingView.findViewById(R.id.prev_btn);
prevButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       Toast.makeText(FloatingViewService.this, "Playing previous song.", Toast.LENGTH_LONG).show();
   }
});


//Set the close button
ImageView closeButton = (ImageView) mFloatingView.findViewById(R.id.close_button);
closeButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       collapsedView.setVisibility(View.VISIBLE);
       expandedView.setVisibility(View.GONE);
   }
});


//Open the application on thi button click
ImageView openButton = (ImageView) mFloatingView.findViewById(R.id.open_button);
openButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       //Open the application  click.
       Intent intent = new Intent(FloatingViewService.this, MainActivity.class);
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       startActivity(intent);


       //close the service and remove view from the view hierarchy
       stopSelf();
   }
});

To drag the floating view along with the user’s touch, we have to override OnTouchListener(). Whenever the user touches the root of the view, we will record the initial x and y coordinates, and when the user moves the finger, the application will calculate the new X and Y coordinate and move the float view.

//Drag and move floating view using user's touch action.
mFloatingView.findViewById(R.id.root_container).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:


               //remember the initial position.
               initialX = params.x;
               initialY = params.y;


               //get the touch location
               initialTouchX = event.getRawX();
               initialTouchY = event.getRawY();
               return true;
           case MotionEvent.ACTION_MOVE:
               //Calculate the X and Y coordinates of the view.
               params.x = initialX + (int) (event.getRawX() - initialTouchX);
               params.y = initialY + (int) (event.getRawY() - initialTouchY);


               //Update the layout with new X & Y coordinate
               mWindowManager.updateViewLayout(mFloatingView, params);
               return true;
       }
       return false;
   }
});

2.2 Handling Widget Collapsing / Expanding

When user clicks on the image view of the collapsed layout, visibility of the collapsed layout should changed to View.GONE and expanded view should become visible. Like below:

facebook-chat-widget-expanding-view

To achieve this we need to implement OnClickListner() to the imageview of the collapsed layout. But, as we implemented OnTouchListener() to the root view, OnClickListner() won’t work. So, to detect clicks we will detect clicks in MotionEvent.ACTION_MOVE in the OnTouchListener() using below code:

case MotionEvent.ACTION_UP:
   int Xdiff = (int) (event.getRawX() - initialTouchX);
   int Ydiff = (int) (event.getRawY() - initialTouchY);


   //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking.
   //So that is click event.
   if (Xdiff < 10 && Ydiff < 10) {
       if (isViewCollapsed()) {
           //When user clicks on the image view of the collapsed layout,
           //visibility of the collapsed layout will be changed to "View.GONE"
           //and expanded view will become visible.
           collapsedView.setVisibility(View.GONE);
           expandedView.setVisibility(View.VISIBLE);
       }
   }
   return true;

So finally your FloatingViewService.java will look like below:

import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.opengl.Visibility;
import android.os.IBinder;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;


public class FloatingViewService extends Service {
   private WindowManager mWindowManager;
   private View mFloatingView;

   public FloatingViewService() {
   }

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

   @Override
   public void onCreate() {
       super.onCreate();
       //Inflate the floating view layout we created
       mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);

       //Add the view to the window.
       final 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);

       //Specify the view position
       params.gravity = Gravity.TOP | Gravity.LEFT;        //Initially view will be added to top-left corner
       params.x = 0;
       params.y = 100;

       //Add the view to the window
       mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
       mWindowManager.addView(mFloatingView, params);

       //The root element of the collapsed view layout
       final View collapsedView = mFloatingView.findViewById(R.id.collapse_view);
       //The root element of the expanded view layout
       final View expandedView = mFloatingView.findViewById(R.id.expanded_container);

       //Set the close button
       ImageView closeButtonCollapsed = (ImageView) mFloatingView.findViewById(R.id.close_btn);
       closeButtonCollapsed.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               //close the service and remove the from from the window
               stopSelf();
           }
       });

       //Set the view while floating view is expanded.
       //Set the play button.
       ImageView playButton = (ImageView) mFloatingView.findViewById(R.id.play_btn);
       playButton.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Toast.makeText(FloatingViewService.this, "Playing the song.", Toast.LENGTH_LONG).show();
           }
       });


       //Set the next button.
       ImageView nextButton = (ImageView) mFloatingView.findViewById(R.id.next_btn);
       nextButton.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Toast.makeText(FloatingViewService.this, "Playing next song.", Toast.LENGTH_LONG).show();
           }
       });


       //Set the pause button.
       ImageView prevButton = (ImageView) mFloatingView.findViewById(R.id.prev_btn);
       prevButton.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Toast.makeText(FloatingViewService.this, "Playing previous song.", Toast.LENGTH_LONG).show();
           }
       });


       //Set the close button
       ImageView closeButton = (ImageView) mFloatingView.findViewById(R.id.close_button);
       closeButton.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               collapsedView.setVisibility(View.VISIBLE);
               expandedView.setVisibility(View.GONE);
           }
       });


       //Open the application on thi button click
       ImageView openButton = (ImageView) mFloatingView.findViewById(R.id.open_button);
       openButton.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               //Open the application  click.
               Intent intent = new Intent(FloatingViewService.this, MainActivity.class);
               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
               startActivity(intent);


               //close the service and remove view from the view hierarchy
               stopSelf();
           }
       });

       //Drag and move floating view using user's touch action.
       mFloatingView.findViewById(R.id.root_container).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:

                       //remember the initial position.
                       initialX = params.x;
                       initialY = params.y;

                       //get the touch location
                       initialTouchX = event.getRawX();
                       initialTouchY = event.getRawY();
                       return true;
                   case MotionEvent.ACTION_UP:
                       int Xdiff = (int) (event.getRawX() - initialTouchX);
                       int Ydiff = (int) (event.getRawY() - initialTouchY);


                       //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking.
                       //So that is click event.
                       if (Xdiff < 10 && Ydiff < 10) {
                           if (isViewCollapsed()) {
                               //When user clicks on the image view of the collapsed layout,
                               //visibility of the collapsed layout will be changed to "View.GONE"
                               //and expanded view will become visible.
                               collapsedView.setVisibility(View.GONE);
                               expandedView.setVisibility(View.VISIBLE);
                           }
                       }
                       return true;
                   case MotionEvent.ACTION_MOVE:
                       //Calculate the X and Y coordinates of the view.
                       params.x = initialX + (int) (event.getRawX() - initialTouchX);
                       params.y = initialY + (int) (event.getRawY() - initialTouchY);


                       //Update the layout with new X & Y coordinate
                       mWindowManager.updateViewLayout(mFloatingView, params);
                       return true;
               }
               return false;
           }
       });
   }


   /**
    * Detect if the floating view is collapsed or expanded.
    *
    * @return true if the floating view is collapsed.
    */
   private boolean isViewCollapsed() {
       return mFloatingView == null || mFloatingView.findViewById(R.id.collapse_view).getVisibility() == View.VISIBLE;
   }


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

2.3 Handle Overdraw permission

Now one final step is remaining is adding floating view by starting the FloatingViewService. For that, we need to check if the application has android.permission.SYSTEM_ALERT_WINDOW permission or not? For android version <= API22, this permission is granted by default. But for the android versions running API > 22, we need to check for the permission runtime.

If the permission is not available, we will open permission management screen to allow the user to grant permission using Settings.ACTION_MANAGE_OVERLAY_PERMISSION intent action. This will open below screen facilitate user to grant android.permission.SYSTEM_ALERT_WINDOW permission.

Here is the code snippet for the MainActivity that will display the floating view when button is clicked by checking the SYSTEM_ALERT_WINDOW permission.

import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity {
   private static final int CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       //Check if the application has draw over other apps permission or not?
       //This permission is by default available for API<23. But for API > 23
       //you have to ask for the permission in runtime.
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {


           //If the draw over permission is not available open the settings screen
           //to grant the permission.
           Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                   Uri.parse("package:" + getPackageName()));
           startActivityForResult(intent, CODE_DRAW_OVER_OTHER_APP_PERMISSION);
       } else {
           initializeView();
       }
   }

   /**
    * Set and initialize the view elements.
    */
   private void initializeView() {
       findViewById(R.id.notify_me).setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               startService(new Intent(MainActivity.this, FloatingViewService.class));
               finish();
           }
       });
   }

   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {
           //Check if the permission is granted or not.
           if (resultCode == RESULT_OK) {
               initializeView();
           } else { //Permission is not available
               Toast.makeText(this,
                       "Draw over other app permission not available. Closing the application",
                       Toast.LENGTH_SHORT).show();

               finish();
           }
       } else {
           super.onActivityResult(requestCode, resultCode, data);
       }
   }
}
android-overdraw-permission

That’s it. Now build and run the project to see the results. You can check out the below image to see the sample in action.

android-floating-chat-widget-like-facebook

Don’t worry if you have any problems while building the project. If you have any queries let me know in comments below.

I am an Android Developer and Machine Learner, based on Ahmedabad. I love to writing complex articles on android. I have a passion for building new things by continuously learning new things.
  • Wow! Thank you once more for this great tutorial!

    • Yup! Cool article. Thanks to Keval Patel.

  • Kunal Agrawal

    hey ravi your tutorials are really helpful ,can u pls also provide tutorials for user profile in like twitter ,fb or linked in old be really helpful.thanks again

    • Thanks Kunal for your suggestion.

      • Kunal Agrawal

        Thanks for your reply when this tutorial will out 🙂

        • It takes time as I am working on other articles.

  • Mouad Ghandi

    Thanks a lot Keval Patel, Could you provide us some tutos or links about animations

  • ARASHI Funsho

    Great Tutorial…. Can’t wait to implement this…. Cheers man

  • Krunal Kapadia

    Thank a lot Keval for this tutorial. Very easy and understandable code.

    • Keval Patel

      Thank you Krunal.

  • Neha Sharma

    Really Helpful and Great Tutorial… you guys are doing well …
    Thanx for this

    • Keval Patel

      Thank you Neha.

  • Pritish Joshi

    Hello,
    Where we can post our requests for new tutorials

    like syncing data between application and web server

  • Le Thanh Tan

    Thanks so much, It’s really wolderful.

    • Keval Patel

      Thanx man.😊

  • ragu gandhi

    this code was perfectly good. i removed music_player image file instead of i added one edit text but its not working could you give solution to this error

  • Augusto Gonzalez

    Where is the id notify_me?

    • Neha Sharma

      notify_me is id of button in contain_main.xml file.I suggest you to download whole project from above its better for u.

    • М. Түвшинтөгс

      Give me download link please

      • Its there at the beginning of the article.

    • Huy Đỗ

      you create in layout_activity_main: a one button with id = notify_me
      Good luck

  • Androider swiftter

    Can you implement a method to take a screen shot by this Floating Widget

  • tertert

    How i can show two icon?

  • Ha Ngoc

    wolderful

  • Abhishek Kaswan

    Ravi Tamada for this great tutorial.

  • guest

    Hey, i want show a multiple icon, How i can do it?

    • guest

      hej?

  • Gokul Sreenivasan

    Hey Ravi tamada ,,, Great tutorial it’s really helpful for us

    • Thanks Gokul.

      • Kalim Ahmad

        Plz bro kya aap music player activity bana sakte ho jo json se data collect krta ho? aur notification player aur minimize krte hi neeche aur activities py b player neeche rehta ho with art image? audio url se play krta ho?

  • A. Badakhshan

    Hi. Thank you for this great tutorial. I wonder can we have an EditText inside expanded layout?

  • Harish Penta

    hello sir.. thanks for this tutorial.
    Its really helpful,but what i need is.. like i want to display my app in sticky mode only when user opens whatsapp or messenger app.just like hike does.. so can you please tell me how to do so..
    thanks in advance.

  • Muhammad Hafiez

    Thanks for the tut,
    how do i make the bubble/chat head that hide at the edge of the screen when using another app or became semi-transparent

  • tech office

    I am not able to find the link for whole project Can you please give me the link..

  • Karthk Mukesh

    I tried the same concept for android wear but failed to get the output. Is it possible to use this for wear also

  • Kalim Ahmad

    Plz bro kya aap music player activity bana sakte ho jo json se data collect krta ho? aur notification player aur minimize krte hi neeche aur activities py b player neeche rehta ho with art image? audio url se play krta ho?

  • wajidkhan

    Very nice

  • Mrityunjay Kumar

    Nice working code but the widget disappears when I remove the app for background even after providing the required permission!

    • Vaibhav Kadam

      Use foreground service

  • Nayan_Dabhi

    Really great tutorial & easy and clean code for implement this tutorial.

    Thankss @disqus_KxHzkEj50f:disqus & @ravi8x:disqus

  • manoj

    Can we use the same implementation inside the application itself? means chathead should not come out from the application.

  • Peter Wesley Odom

    Is this code licensed at all? Open source, or is it free? It’s vey helpful and i don’t want to get in trouble if i use it for a project…

  • shivnay tiwari

    sir first of all i would like to thanks you for all your tutorials i always learn something new here.

    this code work very fine but after starting service back button press not working in api 23 marshmallow please suggest some solution .
    thanks again

  • Rodrigo Scorza

    good Job

  • ShivamNagi9

    Hlo sir can you please tell how to make the view go full screen ? Thanks for the awesome article !!

  • Tùng Đỗ Dst

    Whether I can detect press a key like as volume up, volume down, ok on the service? and if can, how to handle it. Thanks!

  • lukikow

    There is any idea to create a floating button which will be overlay only home screen?

  • Jagdeep Singh

    Androidhive is the best website.. <3