Tuesday, January 7, 2014

System Overlay Demo


Create new project or download project source code from git  https://github.com/cm-nagariya/demo-chirag/tree/master/SystemOverlay

1. Add following permission on AndroidManifest.xml file


<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
    <uses-permission android:name="android.permission.RESTART_PACKAGES" />
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2. Create RadialMenu View

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Toast;

public class RadialMenuWidget extends View {

    //Defines the interface
    public interface RadialMenuEntry {
          public String getName();
          public String getLabel();
          public int getIcon();
          public List<RadialMenuEntry> getChildren();
          public void menuActiviated();
    }  

   
    private List<RadialMenuEntry> menuEntries = new ArrayList<RadialMenuEntry>();
    private RadialMenuEntry centerCircle = null;
   
    private float screen_density = getContext().getResources().getDisplayMetrics().density;
   
    private int defaultColor = Color.rgb(34, 96, 120);     //default color of wedge pieces
    private int defaultAlpha = 180;                          //transparency of the colors, 255=Opague, 0=Transparent
    private int wedge2Color = Color.rgb(50, 50, 50);     //default color of wedge pieces
    private int wedge2Alpha = 210;
    private int outlineColor = Color.rgb(150, 150, 150);      //color of outline
    private int outlineAlpha = 255;                            //transparency of outline
    private int selectedColor = Color.rgb(70, 130, 180);      //color to fill when something is selected
    private int selectedAlpha = 210;                        //transparency of fill when something is selected

    private int disabledColor = Color.rgb(34, 96, 120);      //color to fill when something is selected
    private int disabledAlpha = 100;                        //transparency of fill when something is selected
   
    private int pictureAlpha = 255;                            //transparency of images

    private int textColor = Color.rgb(255, 255, 255);      //color to fill when something is selected
    private int textAlpha = 255;                        //transparency of fill when something is selected

    private int headerTextColor = Color.rgb(255, 255, 255);      //color of header text
    private int headerTextAlpha = 255;                            //transparency of header text
    private int headerBackgroundColor =  Color.rgb(0, 0, 0);    //color of header background
    private int headerBackgroundAlpha =  180;                    //transparency of header background
   
    private int wedgeQty = 1;                //Number of wedges
    private Wedge[] Wedges = new Wedge[wedgeQty];
    private Wedge selected = null;            //Keeps track of which wedge is selected
    private Wedge enabled = null;            //Keeps track of which wedge is enabled for outer ring
    private Rect[] iconRect = new Rect[wedgeQty];


    private int wedgeQty2 = 1;                //Number of wedges
    private Wedge[] Wedges2 = new Wedge[wedgeQty2];
    private Wedge selected2 = null;            //Keeps track of which wedge is selected
    private Rect[] iconRect2 = new Rect[wedgeQty2];
    private RadialMenuEntry wedge2Data = null;        //Keeps track off which menuItem data is being used for the outer ring
   
    private int MinSize = scalePX(35);                //Radius of inner ring size
    private int MaxSize = scalePX(90);                //Radius of outer ring size
    private int r2MinSize = MaxSize+scalePX(5);        //Radius of inner second ring size
    private int r2MaxSize = r2MinSize+scalePX(45);    //Radius of outer second ring size
    private int MinIconSize = scalePX(15);                    //Min Size of Image in Wedge
    private int MaxIconSize = scalePX(35);            //Max Size of Image in Wedge
    //private int BitmapSize = scalePX(40);            //Size of Image in Wedge
    private int cRadius = MinSize-scalePX(7);          //Inner Circle Radius
    private int textSize = scalePX(15);                //TextSize
    private int animateTextSize = textSize;
   
    private int xPosition = scalePX(120);            //Center X location of Radial Menu
    private int yPosition = scalePX(120);            //Center Y location of Radial Menu

    private int xSource = 0;            //Source X of clicked location
    private int ySource = 0;            //Center Y of clicked location
    private boolean showSource = false;    //Display icon where at source location
   
    private boolean inWedge = false;        //Identifies touch event was in first wedge
    private boolean inWedge2 = false;        //Identifies touch event was in second wedge
    private boolean inCircle = false;        //Identifies touch event was in middle circle

    private boolean Wedge2Shown = false;        //Identifies 2nd wedge is drawn
    private boolean HeaderBoxBounded = false;    //Identifies if header box is drawn
   
    private String headerString = null;
    private int headerTextSize = textSize;                //TextSize
    private int headerBuffer = scalePX(8);
    private Rect textRect = new Rect();
    private RectF textBoxRect = new RectF();
    private int headerTextLeft;
    private int headerTextBottom;
   
    private RotateAnimation rotate;
    private AlphaAnimation blend;
    private ScaleAnimation scale;
    private TranslateAnimation move;
    private AnimationSet spriteAnimation;
    private long animationSpeed = 400L;
   

    private static final int ANIMATE_IN = 1;
    private static final int ANIMATE_OUT = 2;
   
    private int animateSections = 4;
    private int r2VariableSize;
    private boolean animateOuterIn = false;
    private boolean animateOuterOut = false;
   
   
   
    public RadialMenuWidget(Context context) {
        super(context);

        // Gets screen specs and defaults to center of screen
        this.xPosition = (getResources().getDisplayMetrics().widthPixels)/2;
        this.yPosition = (getResources().getDisplayMetrics().heightPixels)/2;
      
        determineWedges();
        onOpenAnimation();
    }

   
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        int state = e.getAction();
        int eventX = (int) e.getX();
        int eventY = (int) e.getY();
        if (state == MotionEvent.ACTION_DOWN) {
            //selected = null;
            //selected2 = null;
            inWedge = false;
            inWedge2 = false;
            inCircle = false;


            //Checks if a pie slice is selected in first Wedge
            for (int i = 0; i < Wedges.length; i++) {
                Wedge f = Wedges[i];
                double slice = (2*Math.PI) / wedgeQty;
                double start = (2*Math.PI)*(0.75) - (slice/2);        //this is done so top slice is the centered on top of the circle

                inWedge = pntInWedge(eventX, eventY,
                        xPosition, yPosition,
                        MinSize, MaxSize,
                        (i* slice)+start, slice);                  
              
                if (inWedge == true) {
                    selected = f;
                    break;
                }
            }

          
            //Checks if a pie slice is selected in second Wedge
            if (Wedge2Shown == true) {
                for (int i = 0; i < Wedges2.length; i++) {
                    Wedge f = Wedges2[i];
                    double slice = (2*Math.PI) / wedgeQty2;
                    double start = (2*Math.PI)*(0.75) - (slice/2);        //this is done so top slice is the centered on top of the circle
   
                    inWedge2 = pntInWedge(eventX, eventY,
                            xPosition, yPosition,
                            r2MinSize, r2MaxSize,
                            (i* slice)+start, slice);                  
                  
                    if (inWedge2 == true) {
                        selected2 = f;
                        break;
                    }
                }

            }
          
            //Checks if center circle is selected
            inCircle = pntInCircle(eventX, eventY, xPosition,yPosition,cRadius);

        } else if (state == MotionEvent.ACTION_UP) {
            //execute commands...
            //put in stuff here to "return" the button that was pressed.
            if (inCircle == true) {
                if (Wedge2Shown == true) {
                    enabled = null;
                    animateOuterIn = true;  //sets Wedge2Shown = false;
                }
                selected = null;
                Toast.makeText(getContext(), centerCircle.getName() + " pressed.", Toast.LENGTH_SHORT).show();
                centerCircle.menuActiviated();

            } else if (selected != null){
                for (int i = 0; i < Wedges.length; i++) {
                    Wedge f = Wedges[i];
                    if (f == selected) {
                      
                        //Checks if a inner ring is enabled if so closes the outer ring an
                        if (enabled != null) {
                            Toast.makeText(getContext(), "Closing outer ring", Toast.LENGTH_SHORT).show();
                            enabled = null;
                            animateOuterIn = true;  //sets Wedge2Shown = false;
                          
                        //If outer ring is not enabled, then executes event
                        } else {
                            Toast.makeText(getContext(), menuEntries.get(i).getName() + " pressed.", Toast.LENGTH_SHORT).show();
                            menuEntries.get(i).menuActiviated();
                          
                            //Figures out how many outer rings
                            if (menuEntries.get(i).getChildren() != null) {
                                determineOuterWedges(menuEntries.get(i));
                                enabled = f;
                                animateOuterOut = true;  //sets Wedge2Shown = true;
                              
                            } else {
                                Wedge2Shown = false;
                            }
                          
                        }
                        selected = null;
                    }                  
                }
            } else if (selected2 != null){
                for (int i = 0; i < Wedges2.length; i++) {
                    Wedge f = Wedges2[i];
                    if (f == selected2) {
                    Toast.makeText(getContext(), wedge2Data.getChildren().get(i).getName() + " pressed.", Toast.LENGTH_SHORT).show();
                    animateOuterIn = true;  //sets Wedge2Shown = false;
                    enabled = null;
                    selected = null;
                    }                  
                }
            } else {
                //This is when something outside the circle or any of the rings is selected
                Toast.makeText(getContext(), "Area outside rings pressed.", Toast.LENGTH_SHORT).show();

                //selected = null;
                //enabled = null;
            }
            //selected = null;
            selected2 = null;
            inCircle = false;
        }
        invalidate();
        return true;
    }


    @Override
    protected void onDraw(Canvas c) {

      
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(3);

        // draws a dot at the source of the press
        if (showSource == true ) {
            paint.setColor(outlineColor);
            paint.setAlpha(outlineAlpha);
            paint.setStyle(Paint.Style.STROKE);
            c.drawCircle(xSource, ySource, cRadius/10, paint);
   
            paint.setColor(selectedColor);
            paint.setAlpha(selectedAlpha);
            paint.setStyle(Paint.Style.FILL);
            c.drawCircle(xSource, ySource, cRadius/10, paint);
        }
      
     
         for (int i = 0; i < Wedges.length; i++) {
            Wedge f = Wedges[i];
            paint.setColor(outlineColor);
            paint.setAlpha(outlineAlpha);
            paint.setStyle(Paint.Style.STROKE);
            c.drawPath(f, paint);
            if (f == enabled && Wedge2Shown == true) {
                paint.setColor(wedge2Color);
                paint.setAlpha(wedge2Alpha);
                paint.setStyle(Paint.Style.FILL);
                c.drawPath(f, paint);
            } else if (f != enabled && Wedge2Shown == true) {
                paint.setColor(disabledColor);
                paint.setAlpha(disabledAlpha);
                paint.setStyle(Paint.Style.FILL);
                c.drawPath(f, paint);          
            } else if (f == enabled && Wedge2Shown == false) {
                paint.setColor(wedge2Color);
                paint.setAlpha(wedge2Alpha);
                paint.setStyle(Paint.Style.FILL);
                c.drawPath(f, paint);
            } else if (f == selected) {
                paint.setColor(wedge2Color);
                paint.setAlpha(wedge2Alpha);
                paint.setStyle(Paint.Style.FILL);
                c.drawPath(f, paint);  
            } else {
                paint.setColor(defaultColor);
                paint.setAlpha(defaultAlpha);
                paint.setStyle(Paint.Style.FILL);
                c.drawPath(f, paint);
            }

            Rect rf = iconRect[i];

            if ((menuEntries.get(i).getIcon() != 0) && (menuEntries.get(i).getLabel() != null)) {
              
                //This will look for a "new line" and split into multiple lines                  
                String menuItemName = menuEntries.get(i).getLabel();
                String[] stringArray = menuItemName.split("\n");

                paint.setColor(textColor);
                if (f != enabled && Wedge2Shown == true) {
                    paint.setAlpha(disabledAlpha);
                } else {
                    paint.setAlpha(textAlpha);
                }
                paint.setStyle(Paint.Style.FILL);
                paint.setTextSize(textSize);
              
                Rect rect = new Rect();
                float textHeight = 0;
                for (int j = 0; j < stringArray.length; j++)
                    {
                    paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                    textHeight = textHeight+(rect.height()+3);
                    }

                Rect rf2 = new Rect();
                rf2.set(rf.left, rf.top-((int)textHeight/2), rf.right, rf.bottom-((int)textHeight/2));

                float textBottom = rf2.bottom;
                for (int j = 0; j < stringArray.length; j++)
                    {
                    paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                    float textLeft = rf.centerX() - rect.width()/2;
                    textBottom = textBottom + (rect.height()+3);
                    c.drawText(stringArray[j], textLeft-rect.left, textBottom-rect.bottom, paint);
                    }
                          
                //Puts in the Icon
                Drawable drawable = getResources().getDrawable(menuEntries.get(i).getIcon());              
                drawable.setBounds(rf2);
                if (f != enabled && Wedge2Shown == true) {
                    drawable.setAlpha(disabledAlpha);
                } else {
                    drawable.setAlpha(pictureAlpha);
                }
                drawable.draw(c);                  

        //Icon Only
            } else if (menuEntries.get(i).getIcon() != 0) {
                //Puts in the Icon
                Drawable drawable = getResources().getDrawable(menuEntries.get(i).getIcon());              
                drawable.setBounds(rf);
                if (f != enabled && Wedge2Shown == true) {
                    drawable.setAlpha(disabledAlpha);
                } else {
                    drawable.setAlpha(pictureAlpha);
                }
                drawable.draw(c);              
              
              
        //Text Only                  
            } else {
                //Puts in the Text if no Icon
                paint.setColor(textColor);
                if (f != enabled && Wedge2Shown == true) {
                    paint.setAlpha(disabledAlpha);
                } else {
                    paint.setAlpha(textAlpha);
                }
                paint.setStyle(Paint.Style.FILL);
                paint.setTextSize(textSize);
              
                //This will look for a "new line" and split into multiple lines
                String menuItemName = menuEntries.get(i).getLabel();
                String[] stringArray = menuItemName.split("\n");

                //gets total height
                Rect rect = new Rect();
                float textHeight = 0;
                for (int j = 0; j < stringArray.length; j++)
                    {
                    paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                    textHeight = textHeight+(rect.height()+3);
                    }

                float textBottom = rf.centerY()-(textHeight/2);
                for (int j = 0; j < stringArray.length; j++)
                    {
                    paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                    float textLeft = rf.centerX() - rect.width()/2;
                    textBottom = textBottom + (rect.height()+3);
                    c.drawText(stringArray[j], textLeft-rect.left, textBottom-rect.bottom, paint);
                    }                              
            }          
          
        }

      
        //Animate the outer ring in/out
        if (animateOuterIn == true) {
            animateOuterWedges(ANIMATE_IN);
        }
        else if (animateOuterOut == true) {
            animateOuterWedges(ANIMATE_OUT);
        }          
      
        if (Wedge2Shown == true) {
          
            for (int i = 0; i < Wedges2.length; i++) {
                Wedge f = Wedges2[i];
                paint.setColor(outlineColor);
                paint.setAlpha(outlineAlpha);
                paint.setStyle(Paint.Style.STROKE);
                c.drawPath(f, paint);
                if (f == selected2) {
                    paint.setColor(selectedColor);
                    paint.setAlpha(selectedAlpha);
                    paint.setStyle(Paint.Style.FILL);
                    c.drawPath(f, paint);
                } else {
                    paint.setColor(wedge2Color);
                    paint.setAlpha(wedge2Alpha);
                    paint.setStyle(Paint.Style.FILL);
                    c.drawPath(f, paint);
                }
   
                Rect rf = iconRect2[i];
                if ((wedge2Data.getChildren().get(i).getIcon() != 0) && (wedge2Data.getChildren().get(i).getLabel() != null)) {
                  
                    //This will look for a "new line" and split into multiple lines                  
                    String menuItemName = wedge2Data.getChildren().get(i).getLabel();
                    String[] stringArray = menuItemName.split("\n");

                    paint.setColor(textColor);
                    paint.setAlpha(textAlpha);
                    paint.setStyle(Paint.Style.FILL);
                    paint.setTextSize(animateTextSize);
                  
                    Rect rect = new Rect();
                    float textHeight = 0;
                    for (int j = 0; j < stringArray.length; j++)
                        {
                        paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                        textHeight = textHeight+(rect.height()+3);
                        }

                    Rect rf2 = new Rect();
                    rf2.set(rf.left, rf.top-((int)textHeight/2), rf.right, rf.bottom-((int)textHeight/2));
                  
                    float textBottom = rf2.bottom;
                    for (int j = 0; j < stringArray.length; j++)
                        {
                        paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                        float textLeft = rf.centerX() - rect.width()/2;
                        textBottom = textBottom + (rect.height()+3);
                        c.drawText(stringArray[j], textLeft-rect.left, textBottom-rect.bottom, paint);
                        }
                  
                  
                    //Puts in the Icon
                    Drawable drawable = getResources().getDrawable(wedge2Data.getChildren().get(i).getIcon());
                    drawable.setBounds(rf2);
                    drawable.setAlpha(pictureAlpha);
                    drawable.draw(c);                  

            //Icon Only
                } else if (wedge2Data.getChildren().get(i).getIcon() != 0) {
                    //Puts in the Icon
                    Drawable drawable = getResources().getDrawable(wedge2Data.getChildren().get(i).getIcon());
                    drawable.setBounds(rf);
                    drawable.setAlpha(pictureAlpha);
                    drawable.draw(c);

            //Text Only                  
                } else {
                    //Puts in the Text if no Icon
                    paint.setColor(textColor);
                    paint.setAlpha(textAlpha);
                    paint.setStyle(Paint.Style.FILL);
                    paint.setTextSize(animateTextSize);
                  
                    //This will look for a "new line" and split into multiple lines
                    String menuItemName = wedge2Data.getChildren().get(i).getLabel();
                    String[] stringArray = menuItemName.split("\n");
   
                    //gets total height
                    Rect rect = new Rect();
                    float textHeight = 0;
                    for (int j = 0; j < stringArray.length; j++)
                        {
                        paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                        textHeight = textHeight+(rect.height()+3);
                        }

                    float textBottom = rf.centerY()-(textHeight/2);
                    for (int j = 0; j < stringArray.length; j++)
                        {
                        paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                        float textLeft = rf.centerX() - rect.width()/2;
                        textBottom = textBottom + (rect.height()+3);
                        c.drawText(stringArray[j], textLeft-rect.left, textBottom-rect.bottom, paint);
                        }  
                }
            }
        }
      
        //Draws the Middle Circle
        paint.setColor(outlineColor);
        paint.setAlpha(outlineAlpha);
        paint.setStyle(Paint.Style.STROKE);
        c.drawCircle(xPosition, yPosition, cRadius, paint);
        if (inCircle == true) {
            paint.setColor(selectedColor);
            paint.setAlpha(selectedAlpha);
            paint.setStyle(Paint.Style.FILL);
            c.drawCircle(xPosition, yPosition, cRadius, paint);
            onCloseAnimation();
        } else {
            paint.setColor(defaultColor);
            paint.setAlpha(defaultAlpha);
            paint.setStyle(Paint.Style.FILL);
            c.drawCircle(xPosition, yPosition, cRadius, paint);
        }      
      
      
        // Draw the circle picture
        if ((centerCircle.getIcon() != 0) && (centerCircle.getLabel() != null)) {

            //This will look for a "new line" and split into multiple lines                  
            String menuItemName = centerCircle.getLabel();
            String[] stringArray = menuItemName.split("\n");

            paint.setColor(textColor);
            paint.setAlpha(textAlpha);
            paint.setStyle(Paint.Style.FILL);
            paint.setTextSize(textSize);

            Rect rectText = new Rect();
            Rect rectIcon = new Rect();
            Drawable drawable = getResources().getDrawable(centerCircle.getIcon());

            int h = getIconSize(drawable.getIntrinsicHeight(),MinIconSize,MaxIconSize);
            int w = getIconSize(drawable.getIntrinsicWidth(),MinIconSize,MaxIconSize);          
            rectIcon.set(xPosition-w/2, yPosition-h/2, xPosition+w/2, yPosition+h/2);          
          

            float textHeight = 0;
            for (int j = 0; j < stringArray.length; j++)
                {
                paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rectText);
                textHeight = textHeight+(rectText.height()+3);
                }

            rectIcon.set(rectIcon.left, rectIcon.top-((int)textHeight/2), rectIcon.right, rectIcon.bottom-((int)textHeight/2));

            float textBottom = rectIcon.bottom;
            for (int j = 0; j < stringArray.length; j++)
                {
                paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rectText);
                float textLeft = xPosition - rectText.width()/2;
                textBottom = textBottom + (rectText.height()+3);
                c.drawText(stringArray[j], textLeft-rectText.left, textBottom-rectText.bottom, paint);
                }
          
          
            //Puts in the Icon
            drawable.setBounds(rectIcon);
            drawable.setAlpha(pictureAlpha);
            drawable.draw(c);                  

        //Icon Only
        } else if (centerCircle.getIcon() != 0) {
          
            Rect rect = new Rect();
          
            Drawable drawable = getResources().getDrawable(centerCircle.getIcon());

            int h = getIconSize(drawable.getIntrinsicHeight(),MinIconSize,MaxIconSize);
            int w = getIconSize(drawable.getIntrinsicWidth(),MinIconSize,MaxIconSize);          
            rect.set(xPosition-w/2, yPosition-h/2, xPosition+w/2, yPosition+h/2);
          
            drawable.setBounds(rect);
            drawable.setAlpha(pictureAlpha);
            drawable.draw(c);

        //Text Only              
        } else {
            //Puts in the Text if no Icon
            paint.setColor(textColor);
            paint.setAlpha(textAlpha);
            paint.setStyle(Paint.Style.FILL);
            paint.setTextSize(textSize);
          
            //This will look for a "new line" and split into multiple lines
            String menuItemName = centerCircle.getLabel();
            String[] stringArray = menuItemName.split("\n");

            //gets total height
            Rect rect = new Rect();
            float textHeight = 0;
            for (int j = 0; j < stringArray.length; j++)
                {
                paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                textHeight = textHeight+(rect.height()+3);
                }
          
            float textBottom = yPosition-(textHeight/2);
            for (int j = 0; j < stringArray.length; j++)
                {
                paint.getTextBounds(stringArray[j],0,stringArray[j].length(),rect);
                float textLeft = xPosition - rect.width()/2;
                textBottom = textBottom + (rect.height()+3);
                c.drawText(stringArray[j], textLeft-rect.left, textBottom-rect.bottom, paint);
                }              
                          
          
        }

        // Draws Text in TextBox
        if (headerString != null) {

            paint.setTextSize(headerTextSize);
            paint.getTextBounds(headerString,0,headerString.length(),this.textRect);
            if (HeaderBoxBounded == false) {
                determineHeaderBox();
                HeaderBoxBounded = true;
            }
          
            paint.setColor(outlineColor);
            paint.setAlpha(outlineAlpha);
            paint.setStyle(Paint.Style.STROKE);
            c.drawRoundRect(this.textBoxRect, scalePX(5), scalePX(5), paint);      
            paint.setColor(headerBackgroundColor);
            paint.setAlpha(headerBackgroundAlpha);
            paint.setStyle(Paint.Style.FILL);
            c.drawRoundRect(this.textBoxRect, scalePX(5), scalePX(5), paint);
          
            paint.setColor(headerTextColor);
            paint.setAlpha(headerTextAlpha);
            paint.setStyle(Paint.Style.FILL);
            paint.setTextSize(headerTextSize);
            c.drawText(headerString, headerTextLeft, headerTextBottom, paint);
        }

    }

   
    private int getIconSize(int iconSize, int minSize, int maxSize) {
      
        if (iconSize > minSize) {
            if (iconSize > maxSize) {
                return maxSize;
            } else {    //iconSize < maxSize
                return iconSize;
            }
        } else {  //iconSize < minSize
            return minSize;
        }

    }
   
   
   
    private void onOpenAnimation() {

        rotate = new RotateAnimation(0, 360, xPosition, yPosition);
        //rotate.setRepeatMode(Animation.REVERSE);
        //rotate.setRepeatCount(Animation.INFINITE);
        scale = new ScaleAnimation(0, 1, 0, 1, xPosition, yPosition);
        //scale.setRepeatMode(Animation.REVERSE);
        //scale.setRepeatCount(Animation.INFINITE);
        scale.setInterpolator(new DecelerateInterpolator());
        move = new TranslateAnimation(xSource-xPosition, 0, ySource-yPosition, 0);

        spriteAnimation = new AnimationSet(true);
        //spriteAnimation.addAnimation(rotate);
        spriteAnimation.addAnimation(scale);
        spriteAnimation.addAnimation(move);
        spriteAnimation.setDuration(animationSpeed);

        startAnimation(spriteAnimation);

    }
    private void onCloseAnimation() {
      
        rotate = new RotateAnimation(360, 0, xPosition, yPosition);
        scale = new ScaleAnimation(1, 0, 1, 0, xPosition, yPosition);
        scale.setInterpolator(new AccelerateInterpolator());
        move = new TranslateAnimation(0, xSource-xPosition, 0, ySource-yPosition);

        spriteAnimation = new AnimationSet(true);
        //spriteAnimation.addAnimation(rotate);
        spriteAnimation.addAnimation(scale);
        spriteAnimation.addAnimation(move);
        spriteAnimation.setDuration(animationSpeed);

        startAnimation(spriteAnimation);

    }   
   
    private boolean pntInCircle(double px, double py, double x1, double y1, double radius) {
        double diffX = x1 - px;
        double diffY = y1 - py;
        double dist = diffX*diffX + diffY*diffY;
        if (dist < radius*radius) {
            return true;
            }
        else {
            return false;
            }
        }       
   
   
    private boolean pntInWedge(double px, double py,
            float xRadiusCenter, float yRadiusCenter,
            int innerRadius, int outerRadius,
            double startAngle, double sweepAngle) {
        double diffX = px-xRadiusCenter;
        double diffY = py-yRadiusCenter;
      
        double angle = Math.atan2(diffY,diffX);
        if (angle < 0)
          angle += (2*Math.PI);

        if (startAngle >= (2*Math.PI)) {
            startAngle = startAngle-(2*Math.PI);
        }
      
        //checks if point falls between the start and end of the wedge
        if ((angle >= startAngle && angle <= startAngle + sweepAngle) ||
                (angle+(2*Math.PI) >= startAngle && (angle+(2*Math.PI)) <= startAngle + sweepAngle)) {
          
            // checks if point falls inside the radius of the wedge
            double dist = diffX*diffX + diffY*diffY;
            if (dist < outerRadius*outerRadius && dist > innerRadius*innerRadius) {
                return true;
                }
            }
          return false;
        }

   
    public boolean addMenuEntry( RadialMenuEntry entry )
    {
       menuEntries.add( entry );
       determineWedges();
       return true;
    }

    public boolean setCenterCircle( RadialMenuEntry entry )
    {
       centerCircle = entry;
       return true;
    }
   
   
    public void setInnerRingRadius( int InnerRadius, int OuterRadius )
    {
       this.MinSize = scalePX(InnerRadius);
       this.MaxSize = scalePX(OuterRadius);
       determineWedges();
    }   
   
    public void setOuterRingRadius( int InnerRadius, int OuterRadius )
    {
       this.r2MinSize = scalePX(InnerRadius);
       this.r2MaxSize = scalePX(OuterRadius);    
       determineWedges();
    }   

    public void setCenterCircleRadius( int centerRadius )
    {
       this.cRadius = scalePX(centerRadius);   
       determineWedges();
    }    
   
    public void setTextSize( int TextSize )
    {
       this.textSize = scalePX(TextSize);
       this.animateTextSize = this.textSize;
    }    
   
    public void setIconSize( int minIconSize, int maxIconSize )
    {
       this.MinIconSize = scalePX(minIconSize);
       this.MaxIconSize = scalePX(maxIconSize);
       determineWedges();
    }   
   

    public void setCenterLocation( int x, int y )
    {
       this.xPosition = x;
       this.yPosition = y;
       determineWedges();
       onOpenAnimation();
    }       

    public void setSourceLocation( int x, int y )
    {
       this.xSource = x;
       this.ySource = y;
       onOpenAnimation();
    }     

    public void setShowSourceLocation( boolean showSourceLocation )
    {
       this.showSource = showSourceLocation;
       onOpenAnimation();
    }
   
    public void setAnimationSpeed( long millis )
    {
       this.animationSpeed = millis;
       onOpenAnimation();
    }  
   
    public void setInnerRingColor( int color, int alpha )
    {
       this.defaultColor = color;
       this.defaultAlpha = alpha;
    }    
    public void setOuterRingColor( int color, int alpha )
    {
       this.wedge2Color = color;
       this.wedge2Alpha = alpha;
    }      
    public void setOutlineColor( int color, int alpha )
    {
       this.outlineColor = color;
       this.outlineAlpha = alpha;
    }   
    public void setSelectedColor( int color, int alpha )
    {
       this.selectedColor = color;
       this.selectedAlpha = alpha;
    }      
   
    public void setDisabledColor( int color, int alpha )
    {
       this.disabledColor = color;
       this.disabledAlpha = alpha;
    }      
   
    public void setTextColor( int color, int alpha )
    {
       this.textColor = color;
       this.textAlpha = alpha;
    }     

    public void setHeader( String header, int TextSize )
    {
        this.headerString = header;
        this.headerTextSize = scalePX(TextSize);
        HeaderBoxBounded = false;
    }   
    public void setHeaderColors( int TextColor, int TextAlpha, int BgColor, int BgAlpha )
    {
        this.headerTextColor = TextColor;
        this.headerTextAlpha = TextAlpha;
        this.headerBackgroundColor =  BgColor;
        this.headerBackgroundAlpha =  BgAlpha;

    }     

   
    private int scalePX( int dp_size )
    {
       int px_size = (int) (dp_size * screen_density + 0.5f);
       return px_size;
    }
   
   
   private void animateOuterWedges( int animation_direction) {

           boolean animationComplete = false;
         
     
        //Wedge 2
        float slice2 = 360 / wedgeQty2;
        float start_slice2 = 270 - (slice2/2);
        //calculates where to put the images
        double rSlice2 = (2*Math.PI) / wedgeQty2;
        double rStart2 = (2*Math.PI)*(0.75) - (rSlice2/2);      
      
        this.Wedges2 = new Wedge[wedgeQty2];
        this.iconRect2 = new Rect[wedgeQty2];
      
        Wedge2Shown = true;
      
        int wedgeSizeChange = (r2MaxSize-r2MinSize)/animateSections;
      
        if (animation_direction==ANIMATE_OUT) {
            if ( r2MinSize+r2VariableSize+wedgeSizeChange < r2MaxSize) {
                r2VariableSize += wedgeSizeChange;
            } else {
                animateOuterOut = false;
                r2VariableSize = r2MaxSize - r2MinSize;
                animationComplete = true;
            }
          
            //animates text size change
            this.animateTextSize = (textSize/animateSections) * (r2VariableSize/wedgeSizeChange);
          
            //calculates new wedge sizes
            for (int i = 0; i < Wedges2.length; i++) {
                this.Wedges2[i] = new Wedge(xPosition, yPosition, r2MinSize, r2MinSize+r2VariableSize, (i
                        * slice2)+start_slice2, slice2);
                float xCenter = (float)(Math.cos(((rSlice2*i)+(rSlice2*0.5))+rStart2) * (r2MinSize+r2VariableSize+r2MinSize)/2)+xPosition;
                float yCenter = (float)(Math.sin(((rSlice2*i)+(rSlice2*0.5))+rStart2) * (r2MinSize+r2VariableSize+r2MinSize)/2)+yPosition;

                int h = MaxIconSize;
                int w = MaxIconSize;
                if ( wedge2Data.getChildren().get(i).getIcon() != 0 ) {
                    Drawable drawable = getResources().getDrawable(wedge2Data.getChildren().get(i).getIcon());
                    h = getIconSize(drawable.getIntrinsicHeight(),MinIconSize,MaxIconSize);
                    w = getIconSize(drawable.getIntrinsicWidth(),MinIconSize,MaxIconSize);      
                }

                if (r2VariableSize < h) {
                    h = r2VariableSize;
                }              
                if (r2VariableSize < w) {
                    w = r2VariableSize;
                }                  
              
                this.iconRect2[i] = new Rect((int) xCenter-w/2, (int) yCenter-h/2, (int) xCenter+w/2, (int) yCenter+h/2);
              

                int widthOffset = MaxSize;
                if (widthOffset < this.textRect.width()/2) {
                    widthOffset = this.textRect.width()/2+scalePX(3);
                }
                this.textBoxRect.set((xPosition - (widthOffset)),
                        (int) (yPosition - (r2MinSize+r2VariableSize) - headerBuffer-this.textRect.height()-scalePX(3)),
                        (xPosition + (widthOffset)),
                        (yPosition - (r2MinSize+r2VariableSize) - headerBuffer+scalePX(3)));
                this.headerTextBottom = yPosition - (r2MinSize+r2VariableSize) - headerBuffer-this.textRect.bottom;      
              
            }

        }
        else if (animation_direction==ANIMATE_IN) {
            if ( r2MinSize < r2MaxSize-r2VariableSize-wedgeSizeChange) {
                r2VariableSize += wedgeSizeChange;
            } else {
                animateOuterIn = false;
                r2VariableSize = r2MaxSize;
                animationComplete = true;
            }
          
            //animates text size change
            this.animateTextSize = textSize - ((textSize/animateSections) * (r2VariableSize/wedgeSizeChange));

          
            for (int i = 0; i < Wedges2.length; i++) {
                this.Wedges2[i] = new Wedge(xPosition, yPosition, r2MinSize, r2MaxSize-r2VariableSize, (i
                        * slice2)+start_slice2, slice2);
              
                float xCenter = (float)(Math.cos(((rSlice2*i)+(rSlice2*0.5))+rStart2) * (r2MaxSize-r2VariableSize+r2MinSize)/2)+xPosition;
                float yCenter = (float)(Math.sin(((rSlice2*i)+(rSlice2*0.5))+rStart2) * (r2MaxSize-r2VariableSize+r2MinSize)/2)+yPosition;

                int h = MaxIconSize;
                int w = MaxIconSize;
                if ( wedge2Data.getChildren().get(i).getIcon() != 0 ) {
                    Drawable drawable = getResources().getDrawable(wedge2Data.getChildren().get(i).getIcon());
                    h = getIconSize(drawable.getIntrinsicHeight(),MinIconSize,MaxIconSize);
                    w = getIconSize(drawable.getIntrinsicWidth(),MinIconSize,MaxIconSize);      
                }

                if (r2MaxSize-r2MinSize-r2VariableSize < h) {
                    h = r2MaxSize-r2MinSize-r2VariableSize;
                }              
                if (r2MaxSize-r2MinSize-r2VariableSize < w) {
                    w = r2MaxSize-r2MinSize-r2VariableSize;
                }                  
              
                this.iconRect2[i] = new Rect((int) xCenter-w/2, (int) yCenter-h/2, (int) xCenter+w/2, (int) yCenter+h/2);
              
      
                //computes header text box
                int heightOffset = r2MaxSize-r2VariableSize;  
                int widthOffset = MaxSize;
                if (MaxSize > r2MaxSize-r2VariableSize) {heightOffset = MaxSize;}
                if (widthOffset < this.textRect.width()/2) {
                    widthOffset = this.textRect.width()/2+scalePX(3);
                }
                this.textBoxRect.set((xPosition - (widthOffset)),
                        (int) (yPosition - (heightOffset) - headerBuffer-this.textRect.height()-scalePX(3)),
                        (xPosition + (widthOffset)),
                        (yPosition - (heightOffset) - headerBuffer+scalePX(3)));
                this.headerTextBottom = yPosition - (heightOffset) - headerBuffer-this.textRect.bottom;      

            }
        }
       
        if (animationComplete == true) {
            r2VariableSize = 0;
            this.animateTextSize = textSize;
            if (animation_direction==ANIMATE_IN) {
                Wedge2Shown = false;
            }
        }
      
        invalidate();  //re-draws the picture
  }       
  
   private void determineWedges() {

        int entriesQty = menuEntries.size();
        if ( entriesQty > 0) {
            wedgeQty = entriesQty;
          
            float degSlice = 360 / wedgeQty;
            float start_degSlice = 270 - (degSlice/2);
            //calculates where to put the images
            double rSlice = (2*Math.PI) / wedgeQty;
            double rStart = (2*Math.PI)*(0.75) - (rSlice/2);      
          
            this.Wedges = new Wedge[wedgeQty];
            this.iconRect = new Rect[wedgeQty];
                  
            for (int i = 0; i < Wedges.length; i++) {
                this.Wedges[i] = new Wedge(xPosition, yPosition, MinSize, MaxSize, (i
                        * degSlice)+start_degSlice, degSlice);
                float xCenter = (float)(Math.cos(((rSlice*i)+(rSlice*0.5))+rStart) * (MaxSize+MinSize)/2)+xPosition;
                float yCenter = (float)(Math.sin(((rSlice*i)+(rSlice*0.5))+rStart) * (MaxSize+MinSize)/2)+yPosition;
              
                int h = MaxIconSize;
                int w = MaxIconSize;
                if ( menuEntries.get(i).getIcon() != 0 ) {
                    Drawable drawable = getResources().getDrawable(menuEntries.get(i).getIcon());
                    h = getIconSize(drawable.getIntrinsicHeight(),MinIconSize,MaxIconSize);
                    w = getIconSize(drawable.getIntrinsicWidth(),MinIconSize,MaxIconSize);
                }
              
                this.iconRect[i] = new Rect( (int) xCenter-w/2, (int) yCenter-h/2, (int) xCenter+w/2, (int) yCenter+h/2);
            }
          
            invalidate();  //re-draws the picture
        }
   }       
  
   private void determineOuterWedges(RadialMenuEntry entry) {

        int entriesQty = entry.getChildren().size();
        wedgeQty2 = entriesQty;
     
        //Wedge 2
        float degSlice2 = 360 / wedgeQty2;
        float start_degSlice2 = 270 - (degSlice2/2);
       //calculates where to put the images
        double rSlice2 = (2*Math.PI) / wedgeQty2;
        double rStart2 = (2*Math.PI)*(0.75) - (rSlice2/2);      
      
        this.Wedges2 = new Wedge[wedgeQty2];
        this.iconRect2 = new Rect[wedgeQty2];
              
        for (int i = 0; i < Wedges2.length; i++) {
            this.Wedges2[i] = new Wedge(xPosition, yPosition, r2MinSize, r2MaxSize, (i
                    * degSlice2)+start_degSlice2, degSlice2);
            float xCenter = (float)(Math.cos(((rSlice2*i)+(rSlice2*0.5))+rStart2) * (r2MaxSize+r2MinSize)/2)+xPosition;
            float yCenter = (float)(Math.sin(((rSlice2*i)+(rSlice2*0.5))+rStart2) * (r2MaxSize+r2MinSize)/2)+yPosition;

            int h = MaxIconSize;
            int w = MaxIconSize;
            if ( entry.getChildren().get(i).getIcon() != 0 ) {
                Drawable drawable = getResources().getDrawable(entry.getChildren().get(i).getIcon());
                h = getIconSize(drawable.getIntrinsicHeight(),MinIconSize,MaxIconSize);
                w = getIconSize(drawable.getIntrinsicWidth(),MinIconSize,MaxIconSize);
            }          
            this.iconRect2[i] = new Rect((int) xCenter-w/2, (int) yCenter-h/2, (int) xCenter+w/2, (int) yCenter+h/2);
        }
        this.wedge2Data = entry;
        invalidate();  //re-draws the picture
  }       
  
   private void determineHeaderBox() {

        this.headerTextLeft = xPosition - this.textRect.width()/2;
        this.headerTextBottom = yPosition - (MaxSize) - headerBuffer-this.textRect.bottom;
        int offset = MaxSize;
        if (offset < this.textRect.width()/2) {
            offset = this.textRect.width()/2+scalePX(3);
        }
      
        this.textBoxRect.set((xPosition - (offset)),
                (int) (yPosition - (MaxSize) - headerBuffer-this.textRect.height()-scalePX(3)),
                (xPosition + (offset)),
                (yPosition - (MaxSize) - headerBuffer+scalePX(3)));
   
    }
  
    public class Wedge extends Path {
        private int x, y;
        private int InnerSize, OuterSize;
        private float StartArc;
        private float ArcWidth;
      
        private Wedge(int x, int y, int InnerSize, int OuterSize, float StartArc, float ArcWidth) {
            super();
          
            if (StartArc >= 360) {
                StartArc = StartArc-360;
            }
          
            this.x = x; this.y = y;
            this.InnerSize = InnerSize;
            this.OuterSize = OuterSize;
            this.StartArc = StartArc;
            this.ArcWidth = ArcWidth;
            this.buildPath();
        }
      
        private void buildPath() {

            final RectF rect = new RectF();
            final RectF rect2 = new RectF();
          
            //Rectangles values
            rect.set(this.x-this.InnerSize, this.y-this.InnerSize, this.x+this.InnerSize, this.y+this.InnerSize);
            rect2.set(this.x-this.OuterSize, this.y-this.OuterSize, this.x+this.OuterSize, this.y+this.OuterSize);
                 
            this.reset();
            //this.moveTo(100, 100);
            this.arcTo(rect2, StartArc, ArcWidth);
            this.arcTo(rect, StartArc+ArcWidth, -ArcWidth);
                  
            this.close();


        }
    }

}

3. Create New Service class SystemOverlayService.class

Write following code on that code

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import android.widget.Toast;

public class SystemOverlayService extends Service implements OnTouchListener, OnClickListener {
    private View topLeftView;

    private Button overlayedButton;
    private float offsetX;
    private float offsetY;
    private int originalXPos;
    private int originalYPos;
    private boolean moving;
    private WindowManager wm;

    private RadialMenuWidget PieMenu;

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

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

        wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

        PieMenu = new RadialMenuWidget(getBaseContext());

        int xLayoutSize = wm.getDefaultDisplay().getWidth();
        int yLayoutSize = wm.getDefaultDisplay().getHeight();

        PieMenu.setAnimationSpeed(0L);
        PieMenu.setSourceLocation(xLayoutSize, yLayoutSize);
        PieMenu.setIconSize(15, 30);
        PieMenu.setTextSize(13);

        PieMenu.setCenterCircle(new Close());
        PieMenu.addMenuEntry(new Menu1());
        PieMenu.addMenuEntry(new NewTestMenu());
        PieMenu.addMenuEntry(new CircleOptions());
        PieMenu.addMenuEntry(new Menu2());
        PieMenu.addMenuEntry(new Menu3());

        overlayedButton = new Button(this);
        overlayedButton.setText("Overlay button");
        overlayedButton.setOnTouchListener(this);
        overlayedButton.setBackgroundColor(0x55fe4444);
        overlayedButton.setOnClickListener(this);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.LEFT | Gravity.TOP;
        params.x = 0;
        params.y = 0;
        wm.addView(overlayedButton, params);

        topLeftView = new View(this);
        WindowManager.LayoutParams topLeftParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT);
        topLeftParams.gravity = Gravity.LEFT | Gravity.TOP;
        topLeftParams.x = 0;
        topLeftParams.y = 0;
        topLeftParams.width = 0;
        topLeftParams.height = 0;
        wm.addView(topLeftView, topLeftParams);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (overlayedButton != null) {
            wm.removeView(overlayedButton);
            wm.removeView(topLeftView);
            overlayedButton = null;
            topLeftView = null;
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            float x = event.getRawX();
            float y = event.getRawY();

            moving = false;

            int[] location = new int[2];
            overlayedButton.getLocationOnScreen(location);

            originalXPos = location[0];
            originalYPos = location[1];

            offsetX = originalXPos - x;
            offsetY = originalYPos - y;

        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            int[] topLeftLocationOnScreen = new int[2];
            topLeftView.getLocationOnScreen(topLeftLocationOnScreen);

            System.out.println("topLeftY=" + topLeftLocationOnScreen[1]);
            System.out.println("originalY=" + originalYPos);
            float x = event.getRawX();
            float y = event.getRawY();

            WindowManager.LayoutParams params = (LayoutParams) overlayedButton.getLayoutParams();

            int newX = (int) (offsetX + x);
            int newY = (int) (offsetY + y);

            if (Math.abs(newX - originalXPos) < 1 && Math.abs(newY - originalYPos) < 1 && !moving) {
                return false;
            }

            params.x = newX - (topLeftLocationOnScreen[0]);
            params.y = newY - (topLeftLocationOnScreen[1]);

            wm.updateViewLayout(overlayedButton, params);
            moving = true;
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (moving) {
                return true;
            }
        }

        return false;
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(this, "Overlay button click event", Toast.LENGTH_SHORT).show();

        wm.removeView(overlayedButton);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.CENTER;

        wm.addView(PieMenu, params);

    }

    public static class Menu1 implements RadialMenuEntry {
        public String getName() {
            return "Menu1 - No Children";
        }

        public String getLabel() {
            return "Menu1\nTest";
        }

        public int getIcon() {
            return 0;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("Menu #1 Activated - No Children");
        }
    }

    public static class Menu2 implements RadialMenuEntry {
        public String getName() {
            return "Menu2 - Children";
        }

        public String getLabel() {
            return "Menu2";
        }

        public int getIcon() {
            return R.drawable.icon;
        }

        private List<RadialMenuEntry> children = new ArrayList<RadialMenuEntry>(Arrays.asList(new StringOnly(), new IconOnly(), new StringAndIcon()));

        public List<RadialMenuEntry> getChildren() {
            return children;
        }

        public void menuActiviated() {
            System.out.println("Menu #2 Activated - Children");
        }
    }

    public static class Menu3 implements RadialMenuEntry {
        public String getName() {
            return "Menu3 - No Children";
        }

        public String getLabel() {
            return null;
        }

        public int getIcon() {
            return R.drawable.icon;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("Menu #3 Activated - No Children");
        }
    }

    public static class IconOnly implements RadialMenuEntry {
        public String getName() {
            return "IconOnly";
        }

        public String getLabel() {
            return null;
        }

        public int getIcon() {
            return R.drawable.icon;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("IconOnly Menu Activated");
        }
    }

    public static class StringAndIcon implements RadialMenuEntry {
        public String getName() {
            return "StringAndIcon";
        }

        public String getLabel() {
            return "String";
        }

        public int getIcon() {
            return R.drawable.icon;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("StringAndIcon Menu Activated");
        }
    }

    public static class StringOnly implements RadialMenuEntry {
        public String getName() {
            return "StringOnly";
        }

        public String getLabel() {
            return "String\nOnly";
        }

        public int getIcon() {
            return 0;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("StringOnly Menu Activated");
        }
    }

    public static class NewTestMenu implements RadialMenuEntry {
        public String getName() {
            return "NewTestMenu";
        }

        public String getLabel() {
            return "New\nTest\nMenu";
        }

        public int getIcon() {
            return 0;
        }

        private List<RadialMenuEntry> children = new ArrayList<RadialMenuEntry>(Arrays.asList(new StringOnly(), new IconOnly()));

        public List<RadialMenuEntry> getChildren() {
            return children;
        }

        public void menuActiviated() {
            System.out.println("New Test Menu Activated");
        }
    }

    public static class CircleOptions implements RadialMenuEntry {
        public String getName() {
            return "CircleOptions";
        }

        public String getLabel() {
            return "Circle\nSymbols";
        }

        public int getIcon() {
            return 0;
        }

        private List<RadialMenuEntry> children = new ArrayList<RadialMenuEntry>(Arrays.asList(new RedCircle(), new YellowCircle(), new GreenCircle(),
                new BlueCircle()));

        public List<RadialMenuEntry> getChildren() {
            return children;
        }

        public void menuActiviated() {
            System.out.println("Circle Options Activated");
        }
    }

    public static class RedCircle implements RadialMenuEntry {
        public String getName() {
            return "RedCircle";
        }

        public String getLabel() {
            return "Red";
        }

        public int getIcon() {
            return R.drawable.red_circle;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("Red Circle Activated");
        }
    }

    public static class YellowCircle implements RadialMenuEntry {
        public String getName() {
            return "YellowCircle";
        }

        public String getLabel() {
            return "Yellow";
        }

        public int getIcon() {
            return R.drawable.yellow_circle;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("Yellow Circle Activated");
        }
    }

    public static class GreenCircle implements RadialMenuEntry {
        public String getName() {
            return "GreenCircle";
        }

        public String getLabel() {
            return "Green";
        }

        public int getIcon() {
            return R.drawable.green_circle;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("Green Circle Activated");
        }
    }

    public static class BlueCircle implements RadialMenuEntry {
        public String getName() {
            return "BlueCircle";
        }

        public String getLabel() {
            return "Blue";
        }

        public int getIcon() {
            return R.drawable.blue_circle;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {
            System.out.println("Blue Circle Activated");
        }
    }

    public class Close implements RadialMenuEntry {

        public String getName() {
            return "Close";
        }

        public String getLabel() {
            return null;
        }

        public int getIcon() {
            return android.R.drawable.ic_menu_close_clear_cancel;
        }

        public List<RadialMenuEntry> getChildren() {
            return null;
        }

        public void menuActiviated() {

            System.out.println("Close Menu Activated");
            //Need to figure out how to to the layout.removeView(PieMenu)
            //ll.removeView(PieMenu);
//            ((WindowManager) PieMenu.getParent()).removeView(PieMenu);
            wm.removeView(PieMenu);
            WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT);
            params.gravity = Gravity.LEFT | Gravity.TOP;
            params.x = 0;
            params.y = 0;
            wm.addView(overlayedButton, params);
        }
    }
}

4. Create Activity to start Service


class ShowView extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent svc = new Intent(this, SystemOverlayService.class);
        startService(svc);
        finish();
    }
}

5. Registered Service on AndroidManifest.xml file

<service
            android:name=".SystemOverlayService"
            android:exported="true" />


6. Use Following drawables on res/drawable folder

--- blue_circle.xml

<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval">
            <solid android:color="#FF000000" />
            <size android:width="16dp" android:height="16dp" />
        </shape>
    </item>
    <item android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp">
        <shape android:shape="oval">
            <solid android:color="#FFFFFFFF" />
        </shape>
    </item>
    <item android:top="4dp" android:left="4dp" android:right="4dp" android:bottom="4dp">
        <shape android:shape="oval">
                <gradient android:startColor="#FF4040FF" android:endColor="#FF0000A0"
            android:angle="270"/>
        </shape>
    </item>    
</layer-list>


--- green_circle.xml

<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval">
            <solid android:color="#FF000000" />
            <size android:width="16dp" android:height="16dp" />
        </shape>
    </item>
    <item android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp">
        <shape android:shape="oval">
            <solid android:color="#FFFFFFFF" />
        </shape>
    </item>
    <item android:top="4dp" android:left="4dp" android:right="4dp" android:bottom="4dp">
        <shape android:shape="oval">
                <gradient android:startColor="#FF40FF40" android:endColor="#FF00A000"
            android:angle="270"/>
        </shape>
    </item>  
</layer-list>

--red_circle.xml


<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval">
            <solid android:color="#FF000000" />
            <size android:width="16dp" android:height="16dp" />
        </shape>
    </item>
    <item android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp">
        <shape android:shape="oval">
            <solid android:color="#FFFFFFFF" />
        </shape>
    </item>
    <item android:top="4dp" android:left="4dp" android:right="4dp" android:bottom="4dp">
        <shape android:shape="oval">
                <gradient android:startColor="#FFFF4040" android:endColor="#FFA00000"
            android:angle="270"/>
        </shape>
    </item>    
</layer-list>

--yellow_circle.xml

<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval">
            <solid android:color="#FF000000" />
            <size android:width="16dp" android:height="16dp" />
        </shape>
    </item>
    <item android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp">
        <shape android:shape="oval">
            <solid android:color="#FFFFFFFF" />
        </shape>
    </item>
    <item android:top="4dp" android:left="4dp" android:right="4dp" android:bottom="4dp">
        <shape android:shape="oval">
                <gradient android:startColor="#FFFFFF40" android:endColor="#FFA0A000"
            android:angle="270"/>
        </shape>
    </item>  
</layer-list>