Tuesday, June 17, 2025

Emotes & FFFF Skins Hub

 



 ðŸ”¹ App Name 🔹 


Emotes & FFFF Skins Hub




Looking for a way to make your character truly YOURS?

With Emotes, Skins & Wallpapers Tool for Battlegrounds, you can customize and celebrate your style in the game!


🔥 Features:


* Large collection of emotes to celebrate, tease, or show off!

* Variety of character skins to personalize your appearance.

* Amazing high-resolution wallpapers featuring your favorite game art.

* Easily preview and select your preferred emotes, skins, and backgrounds.

* All content is for visual expression and customization — this app does not modify game files or provide unfair advantages.


Express yourself, make your character stand out, and enjoy your battlegrounds experience in a whole new way!


Download now and start customizing today!


Privacy Policy - Emotes & FFFF Skins Hub

 ðŸ”¹ Privacy Policy 🔹


Effective Date: Jun 17, 2025


Emotes & FFFF Skins Hub values your privacy. This Privacy Policy explains how we collect, use, and protect your information when you use our application.




 1. Information We Collect


We do not collect any personally identifiable information (such as your name, email, or phone number) directly.

We may collect non-personal information and usage data (such as your device model, operating system version, and interaction with the app) to help us improve your experience.




 2. Storage Permissions (WRITE_EXTERNAL_STORAGE)


This app requests WRITE_EXTERNAL_STORAGE permission in order to:


* Save downloaded or customized emotes, skins, or wallpapers directly to your phone’s gallery.

* Provide you convenient access to these files after they are downloaded.


We do not access or modify any files that are not related to the functionality of this application.




 3. Ad Networks and Monetization


We use AdMob (Google) and Meta (Meta Audience Network) to serve ads in the app.

These ad networks may collect and use certain data to show you relevant and personalized ads. This may include:


* Your approximate location

* Your device’s advertising identifier

* Interaction data with the ad (clicks, views)


For more information, please see their respective Privacy Policies:


[AdMob by Google Privacy Policy](https://policies.google.com/privacy)

[Meta Privacy Policy](https://www.facebook.com/privacy/policy/)




 4. Children's Privacy


We do not knowingly collect or solicit information from children under the age of 13.

If you believe a child under 13 may have provided us with information, please contact us immediately and we will delete it.




 5. Security


We implement appropriate technical and organizational measures to protect your data against unauthorized access, disclosure, or destruction.




 6. Changes to This Privacy Policy


We may update this Privacy Policy from time to time.

Any updated policy will be posted within the app or on the store listing with the new effective date.




 7. Contact Us


If you have any questions or concerns about this Privacy Policy or your data, please contact us at yogirajsinh.work@gmail.com.

Terms of Service - Emotes & FFFF Skins Hub

 ðŸ”¹ Terms of Service 🔹


Effective Date: Jun 17, 2025


Welcome to Emotes & FFFF Skins Hub!

Please read these Terms of Service carefully before using our application.

By accessing or using Emotes & FFFF Skins Hub, you agree to be bound by these terms.




 1. Use of Our App


* Emotes & FFFF Skins Hub is a tool designed for entertainment and customization within games.

* All content provided by Emotes & FFFF Skins Hub (such as emotes, skins, and wallpapers) is for visual expression and personalization.

* We do not modify game files or provide unfair advantages in gameplay.




 2. Permissions


This app requests WRITE_EXTERNAL_STORAGE permission in order to:


* Save downloaded or customized emotes, skins, or wallpapers directly to your phone’s gallery.


We do not modify or delete files that are not related to the functionality of the application.




 3. Advertisements


We use AdMob (Google) and Meta (Meta Audience Network) to monetize this application.

These ad networks may collect and use certain data to show you relevant and personalized ads.

Please see their respective Privacy Policies for more details:


[AdMob by Google Privacy Policy](https://policies.google.com/privacy)

[Meta Privacy Policy](https://www.facebook.com/privacy/policy/)




 4. Intellectual Property


* All content provided by Emotes & FFFF Skins Hub is for entertainment and customization purposes only.

* All trademarks, logos, and game-related content used in this application belong to their respective owners.

* We do not claim ownership over game assets or intellectual property.




 5. Children's Privacy


We do not knowingly collect or solicit information from children under the age of 13.

If you believe a child under 13 may have provided us with information, please contact us immediately and we will delete it.




 6. Limitations of Liability


* Emotes & FFFF Skins Hub is provided “AS IS” and without any warranty.

* We are not liable for any damage, data loss, or other issues that may arise from the use or inability to use this application.




 7. Changes to These Terms of Service


We may update these Terms of Service from time to time.

Any updated terms will be posted within the app or on the store listing with the new effective date.




 8. Contact Us


If you have any questions or concerns about these Terms of Service, please contact us at yogirajsinh.work@gmail.com.



Thursday, May 22, 2025

Terms of Service for Foodify: AI Food Scanner

Terms of Service for Foodify: AI Food Scanner

Effective Date: May 22, 2025

1. Acceptance of Terms

By downloading, installing, or using the Foodify: AI Food Scanner app ("App"), you agree to these Terms of Service ("Terms"). If you do not agree, please do not use the App.

2. Description of Service

Foodify provides users with the ability to scan food barcodes and view nutritional information (e.g., calories, fat, sugar, carbs, protein). The App is designed to help users make more informed dietary choices.

3. User Obligations

  • Eligibility: You must be at least 13 years old to use the App.

  • Personal Use: The App is intended for personal, non-commercial use only.

  • Information Accuracy: You agree to provide accurate information and use the App in accordance with applicable laws.

4. User-Provided Information

To enhance functionality and provide more personalized nutrition insights, the App may request the following information from you:

  • Gender

  • Age

  • Weight

This data helps us estimate your individual nutritional needs. All such information is stored only on your device in a local database and is not transmitted or shared with any external server or third party.

5. Privacy and Data Usage

We respect your privacy. Aside from locally stored data mentioned above, the App does not collect or store personal data on any remote server. We may collect anonymous device identifiers for analytics and improving functionality. For more, refer to our Privacy Policy.

6. Intellectual Property

All content, logos, and features in the App are the intellectual property of the developer and may not be used or reproduced without permission.

7. Disclaimers

  • Nutritional Accuracy: We strive to provide reliable data but cannot guarantee 100% accuracy of nutritional information.

  • Not Medical Advice: This App does not provide medical or dietary advice. Always consult a healthcare professional for nutritional concerns.

8. Limitation of Liability

To the fullest extent permitted by law, we are not liable for any damages arising from use or inability to use the App.

9. Modifications

We may revise these Terms at any time. Updates will be posted within the App, and continued use implies acceptance of those changes.

10. Contact Us

If you have questions or concerns, contact:
Email: abhishekkamani94@gmail.com


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>