├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── deps
│ └── XposedBridgeApi-54.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── m
│ │ └── naman14
│ │ └── powermenu
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── xposed_init
│ ├── java
│ └── com
│ │ └── naman14
│ │ └── powermenu
│ │ ├── BakedBezierInterpolator.java
│ │ ├── CircularRevealView.java
│ │ ├── FabAnimationUtils.java
│ │ ├── Helper.java
│ │ ├── MainActivity.java
│ │ ├── PowerDialog.java
│ │ ├── PreferenceFragment.java
│ │ ├── TextDrawable.java
│ │ └── xposed
│ │ ├── XposedDialog.java
│ │ ├── XposedMain.java
│ │ └── XposedMainActivity.java
│ └── res
│ ├── anim
│ ├── fade_in.xml
│ ├── layout_controller_fade_in.xml
│ ├── layout_controller_push_up_in.xml
│ ├── layout_controller_scale.xml
│ ├── push_up_in.xml
│ ├── scale.xml
│ └── slide_down_out.xml
│ ├── drawable-hdpi
│ ├── close.png
│ ├── ic_reboot.png
│ └── power.png
│ ├── layout
│ ├── activity_main.xml
│ ├── activity_main_xposed.xml
│ └── fragment_power.xml
│ ├── menu
│ └── menu_main.xml
│ ├── values-w820dp
│ └── dimens.xml
│ ├── values
│ ├── arrays.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ ├── styles.xml
│ └── values.xml
│ └── xml
│ └── prefs.xml
├── build.gradle
├── demo.gif
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | *.iml
3 | out
4 | .idea
5 | prebuilts
6 | .DS_Store
7 | local.properties
8 | .gradle
9 | *.apk
10 | *.txt
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MaterialPowerMenu
2 | A demo of the power menu with Reveal and other animations
3 |
4 | Some days ago, I saw a gif on Google+ demonstating a concept of Android Power menu in material design, it contained various Circular Reveal animations introduced in
5 | Lollipop and various other beautiful animations. I was able to replicate the concept using basic xml animations and Circular Reveal APIs. This repository is the demo of
6 | the original concept.
7 |
8 | You can download the app from [Google Play](https://play.google.com/store/apps/details?id=com.naman14.powermenu)
9 |
10 | 
11 |
12 | Concept by Igor Da Silva
13 | https://dribbble.com/shots/1939117-Advanced-Power-Menu-Concept-Android-Lollipop
14 |
15 |
16 | License
17 | ===============
18 | >(c) 2015 Naman Dwivedi
19 |
20 | >Material Power Menu is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
21 |
22 | >This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
23 |
24 | >You should have received a copy of the GNU General Public License along with this app. If not, see .
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | applicationId "com.naman14.powermenu"
9 | minSdkVersion 14
10 | targetSdkVersion 23
11 | versionCode 4
12 | versionName "2.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile 'com.android.support:appcompat-v7:23.1.0'
25 | compile 'eu.chainfire:libsuperuser:1.0.0.+'
26 | compile 'com.android.support:design:23.1.0'
27 | provided fileTree(dir: 'deps', include: ['*.jar'])
28 | }
29 |
--------------------------------------------------------------------------------
/app/deps/XposedBridgeApi-54.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naman14/MaterialPowerMenu/fcbe1061fd8aa1692aabe10a6761189d878b336e/app/deps/XposedBridgeApi-54.jar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/naman/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/m/naman14/powermenu/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
12 |
15 |
18 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/assets/xposed_init:
--------------------------------------------------------------------------------
1 | com.naman14.powermenu.xposed.XposedMain
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/BakedBezierInterpolator.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu;
2 |
3 |
4 | /*
5 | * Copyright (C) 2013 The Android Open Source Project
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 |
21 | import android.view.animation.Interpolator;
22 |
23 | /**
24 | * A pre-baked bezier-curved interpolator for indeterminate progress animations.
25 | */
26 | public final class BakedBezierInterpolator implements Interpolator {
27 | private static final BakedBezierInterpolator INSTANCE = new BakedBezierInterpolator();
28 |
29 | public final static BakedBezierInterpolator getInstance() {
30 | return INSTANCE;
31 | }
32 |
33 | /**
34 | * Use getInstance instead of instantiating.
35 | */
36 | private BakedBezierInterpolator() {
37 | super();
38 | }
39 |
40 | /**
41 | * Lookup table values.
42 | * Generated using a Bezier curve from (0,0) to (1,1) with control points:
43 | * P0 (0,0)
44 | * P1 (0.4, 0)
45 | * P2 (0.2, 1.0)
46 | * P3 (1.0, 1.0)
47 | *
48 | * Values sampled with x at regular intervals between 0 and 1.
49 | */
50 | private static final float[] VALUES = new float[]{
51 | 0.0f, 0.0002f, 0.0009f, 0.0019f, 0.0036f, 0.0059f, 0.0086f, 0.0119f, 0.0157f, 0.0209f,
52 | 0.0257f, 0.0321f, 0.0392f, 0.0469f, 0.0566f, 0.0656f, 0.0768f, 0.0887f, 0.1033f, 0.1186f,
53 | 0.1349f, 0.1519f, 0.1696f, 0.1928f, 0.2121f, 0.237f, 0.2627f, 0.2892f, 0.3109f, 0.3386f,
54 | 0.3667f, 0.3952f, 0.4241f, 0.4474f, 0.4766f, 0.5f, 0.5234f, 0.5468f, 0.5701f, 0.5933f,
55 | 0.6134f, 0.6333f, 0.6531f, 0.6698f, 0.6891f, 0.7054f, 0.7214f, 0.7346f, 0.7502f, 0.763f,
56 | 0.7756f, 0.7879f, 0.8f, 0.8107f, 0.8212f, 0.8326f, 0.8415f, 0.8503f, 0.8588f, 0.8672f,
57 | 0.8754f, 0.8833f, 0.8911f, 0.8977f, 0.9041f, 0.9113f, 0.9165f, 0.9232f, 0.9281f, 0.9328f,
58 | 0.9382f, 0.9434f, 0.9476f, 0.9518f, 0.9557f, 0.9596f, 0.9632f, 0.9662f, 0.9695f, 0.9722f,
59 | 0.9753f, 0.9777f, 0.9805f, 0.9826f, 0.9847f, 0.9866f, 0.9884f, 0.9901f, 0.9917f, 0.9931f,
60 | 0.9944f, 0.9955f, 0.9964f, 0.9973f, 0.9981f, 0.9986f, 0.9992f, 0.9995f, 0.9998f, 1.0f, 1.0f
61 | };
62 |
63 | private static final float STEP_SIZE = 1.0f / (VALUES.length - 1);
64 |
65 | @Override
66 | public float getInterpolation(float input) {
67 | if (input >= 1.0f) {
68 | return 1.0f;
69 | }
70 |
71 | if (input <= 0f) {
72 | return 0f;
73 | }
74 |
75 | int position = Math.min(
76 | (int) (input * (VALUES.length - 1)),
77 | VALUES.length - 2);
78 |
79 | float quantized = position * STEP_SIZE;
80 | float difference = input - quantized;
81 | float weight = difference / STEP_SIZE;
82 |
83 | return VALUES[position] + weight * (VALUES[position + 1] - VALUES[position]);
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/CircularRevealView.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu;
2 |
3 | /**
4 | * Created by naman on 18/03/15.
5 | */
6 |
7 | import android.animation.Animator;
8 | import android.content.Context;
9 | import android.graphics.Color;
10 | import android.graphics.drawable.ShapeDrawable;
11 | import android.graphics.drawable.shapes.OvalShape;
12 | import android.os.Build;
13 | import android.util.AttributeSet;
14 | import android.view.View;
15 | import android.view.ViewGroup;
16 | import android.view.ViewPropertyAnimator;
17 |
18 | public class CircularRevealView extends ViewGroup {
19 |
20 | public static final int ANIMATION_REVEAL = 0;
21 | public static final int ANIMATION_HIDE = 2;
22 |
23 | private static final float SCALE = 8f;
24 |
25 | private View inkView;
26 | private int inkColor;
27 | private ShapeDrawable circle;
28 | private ViewPropertyAnimator animator;
29 |
30 | public CircularRevealView(Context context) {
31 | this(context, null);
32 | }
33 |
34 | public CircularRevealView(Context context, AttributeSet attrs) {
35 | this(context, attrs, 0);
36 | }
37 |
38 | public CircularRevealView(Context context, AttributeSet attrs, int defStyleAttr) {
39 | super(context, attrs, defStyleAttr);
40 |
41 | if (isInEditMode()) {
42 | return;
43 | }
44 |
45 | inkView = new View(context);
46 | addView(inkView);
47 |
48 | circle = new ShapeDrawable(new OvalShape());
49 |
50 | Helper.setBackground(inkView, circle);
51 | inkView.setVisibility(View.INVISIBLE);
52 | }
53 |
54 | @Override
55 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
56 | inkView.layout(left, top, left + inkView.getMeasuredWidth(), top + inkView.getMeasuredHeight());
57 | }
58 |
59 | @Override
60 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
61 | final int width = MeasureSpec.getSize(widthMeasureSpec);
62 | final int height = MeasureSpec.getSize(heightMeasureSpec);
63 | setMeasuredDimension(width, height);
64 |
65 | final float circleSize = (float) Math.sqrt(width * width + height * height) * 2f;
66 | final int size = (int) (circleSize / SCALE);
67 | final int sizeSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
68 | inkView.measure(sizeSpec, sizeSpec);
69 | }
70 |
71 | public void reveal(final int x, final int y, final int color, Animator.AnimatorListener listener) {
72 | final int duration = getResources().getInteger(R.integer.rcv_animationDurationReveal);
73 | reveal(x, y, color, 0, duration, listener);
74 | }
75 |
76 | public void reveal(final int x, final int y, final int color, final int startRadius, long duration, final Animator.AnimatorListener listener) {
77 | if (color == inkColor) {
78 | return;
79 | }
80 | inkColor = color;
81 |
82 | if (animator != null) {
83 | animator.cancel();
84 | }
85 |
86 | circle.getPaint().setColor(color);
87 | inkView.setVisibility(View.VISIBLE);
88 |
89 | final float startScale = startRadius * 2f / inkView.getHeight();
90 | final float finalScale = calculateScale(x, y) * SCALE;
91 |
92 | prepareView(inkView, x, y, startScale);
93 | animator = inkView.animate().scaleX(finalScale).scaleY(finalScale).setDuration(duration).setListener(new Animator.AnimatorListener() {
94 | @Override
95 | public void onAnimationStart(Animator animator) {
96 | if (listener != null) {
97 | listener.onAnimationStart(animator);
98 | }
99 | }
100 |
101 | @Override
102 | public void onAnimationEnd(Animator animation) {
103 | setBackgroundColor(color);
104 | inkView.setVisibility(View.INVISIBLE);
105 | if (listener != null) {
106 | listener.onAnimationEnd(animation);
107 | }
108 | }
109 |
110 | @Override
111 | public void onAnimationCancel(Animator animator) {
112 | if (listener != null) {
113 | listener.onAnimationCancel(animator);
114 | }
115 | }
116 |
117 | @Override
118 | public void onAnimationRepeat(Animator animator) {
119 | if (listener != null) {
120 | listener.onAnimationRepeat(animator);
121 | }
122 | }
123 | });
124 | prepareAnimator(animator, ANIMATION_REVEAL);
125 | animator.start();
126 | }
127 |
128 | public void hide(final int x, final int y, final int color, final Animator.AnimatorListener listener) {
129 | final int duration = getResources().getInteger(R.integer.rcv_animationDurationHide);
130 | hide(x, y, color, 0, duration, listener);
131 | }
132 |
133 | public void hide(final int x, final int y, final int color, final int endRadius, final long duration, final Animator.AnimatorListener listener) {
134 | inkColor = Color.TRANSPARENT;
135 |
136 | if (animator != null) {
137 | animator.cancel();
138 | }
139 |
140 | inkView.setVisibility(View.VISIBLE);
141 | setBackgroundColor(color);
142 |
143 | final float startScale = calculateScale(x, y) * SCALE;
144 | final float finalScale = endRadius * SCALE / inkView.getWidth();
145 |
146 | prepareView(inkView, x, y, startScale);
147 |
148 | animator = inkView.animate().scaleX(finalScale).scaleY(finalScale).setDuration(duration).setListener(new Animator.AnimatorListener() {
149 | @Override
150 | public void onAnimationStart(Animator animator) {
151 | if (listener != null) {
152 | listener.onAnimationStart(animator);
153 | }
154 | }
155 |
156 | @Override
157 | public void onAnimationEnd(Animator animation) {
158 | inkView.setVisibility(View.INVISIBLE);
159 | if (listener != null) {
160 | listener.onAnimationEnd(animation);
161 | }
162 | }
163 |
164 | @Override
165 | public void onAnimationCancel(Animator animator) {
166 | if (listener != null) {
167 | listener.onAnimationCancel(animator);
168 | }
169 | }
170 |
171 | @Override
172 | public void onAnimationRepeat(Animator animator) {
173 | if (listener != null) {
174 | listener.onAnimationRepeat(animator);
175 | }
176 | }
177 | });
178 | prepareAnimator(animator, ANIMATION_HIDE);
179 | animator.start();
180 | }
181 |
182 | public ViewPropertyAnimator prepareAnimator(ViewPropertyAnimator animator, int type) {
183 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
184 | animator.withLayer();
185 | }
186 | animator.setInterpolator(BakedBezierInterpolator.getInstance());
187 | return animator;
188 | }
189 |
190 | private void prepareView(View view, int x, int y, float scale) {
191 | final int centerX = (view.getWidth() / 2);
192 | final int centerY = (view.getHeight() / 2);
193 | view.setTranslationX(x - centerX);
194 | view.setTranslationY(y - centerY);
195 | view.setPivotX(centerX);
196 | view.setPivotY(centerY);
197 | view.setScaleX(scale);
198 | view.setScaleY(scale);
199 | }
200 |
201 | /**
202 | * calculates the required scale of the ink-view to fill the whole view
203 | *
204 | * @param x circle center x
205 | * @param y circle center y
206 | * @return
207 | */
208 | private float calculateScale(int x, int y) {
209 | final float centerX = getWidth() / 2f;
210 | final float centerY = getHeight() / 2f;
211 | final float maxDistance = (float) Math.sqrt(centerX * centerX + centerY * centerY);
212 |
213 | final float deltaX = centerX - x;
214 | final float deltaY = centerY - y;
215 | final float distance = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
216 | final float scale = 0.5f + (distance / maxDistance) * 0.5f;
217 | return scale;
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/FabAnimationUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Naman Dwivedi
3 | *
4 | * Licensed under the GNU General Public License v3
5 | *
6 | * This is free software: you can redistribute it and/or modify it
7 | * under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
9 | *
10 | * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | * See the GNU General Public License for more details.
13 | */
14 |
15 | package com.naman14.powermenu;
16 |
17 | import android.os.Build;
18 | import android.support.v4.view.ViewCompat;
19 | import android.support.v4.view.ViewPropertyAnimatorListener;
20 | import android.support.v4.view.animation.FastOutSlowInInterpolator;
21 | import android.view.View;
22 | import android.view.animation.Animation;
23 | import android.view.animation.AnimationUtils;
24 | import android.view.animation.Interpolator;
25 |
26 | public class FabAnimationUtils {
27 |
28 | private static final long DEFAULT_DURATION = 300L;
29 | private static final Interpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator();
30 |
31 | public static void scaleIn(final View fab) {
32 | scaleIn(fab, DEFAULT_DURATION, null);
33 | }
34 |
35 | public static void scaleIn(final View fab, long duration, final ScaleCallback callback) {
36 | fab.setVisibility(View.VISIBLE);
37 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
38 | ViewCompat.animate(fab)
39 | .scaleX(1.0F)
40 | .scaleY(1.0F)
41 | .alpha(1.0F)
42 | .setDuration(duration)
43 | .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
44 | .withLayer()
45 | .setListener(new ViewPropertyAnimatorListener() {
46 | public void onAnimationStart(View view) {
47 | if (callback != null) callback.onAnimationStart();
48 | }
49 |
50 | public void onAnimationCancel(View view) {
51 | }
52 |
53 | public void onAnimationEnd(View view) {
54 | view.setVisibility(View.VISIBLE);
55 | if (callback != null) callback.onAnimationEnd();
56 | }
57 | }).start();
58 | } else {
59 | Animation anim = AnimationUtils.loadAnimation(fab.getContext(), R.anim.design_fab_out);
60 | anim.setDuration(duration);
61 | anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
62 | anim.setAnimationListener(new Animation.AnimationListener() {
63 | public void onAnimationStart(Animation animation) {
64 | if (callback != null) callback.onAnimationStart();
65 | }
66 |
67 | public void onAnimationEnd(Animation animation) {
68 | fab.setVisibility(View.VISIBLE);
69 | if (callback != null) callback.onAnimationEnd();
70 | }
71 |
72 | @Override
73 | public void onAnimationRepeat(Animation animation) {
74 | //
75 | }
76 | });
77 | fab.startAnimation(anim);
78 | }
79 | }
80 |
81 | public static void scaleOut(final View fab) {
82 | scaleOut(fab, DEFAULT_DURATION, null);
83 | }
84 |
85 | public static void scaleOut(final View fab, final ScaleCallback callback) {
86 | scaleOut(fab, DEFAULT_DURATION, callback);
87 | }
88 |
89 | public static void scaleOut(final View fab, long duration, final ScaleCallback callback) {
90 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
91 | ViewCompat.animate(fab)
92 | .scaleX(0.0F)
93 | .scaleY(0.0F).alpha(0.0F)
94 | .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
95 | .setDuration(duration)
96 | .withLayer()
97 | .setListener(new ViewPropertyAnimatorListener() {
98 | public void onAnimationStart(View view) {
99 | if (callback != null) callback.onAnimationStart();
100 | }
101 |
102 | public void onAnimationCancel(View view) {
103 | }
104 |
105 | public void onAnimationEnd(View view) {
106 | view.setVisibility(View.INVISIBLE);
107 | if (callback != null) callback.onAnimationEnd();
108 | }
109 | }).start();
110 | } else {
111 | Animation anim = AnimationUtils.loadAnimation(fab.getContext(), R.anim.design_fab_out);
112 | anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
113 | anim.setDuration(duration);
114 | anim.setAnimationListener(new Animation.AnimationListener() {
115 | public void onAnimationStart(Animation animation) {
116 | if (callback != null) callback.onAnimationStart();
117 | }
118 |
119 | public void onAnimationEnd(Animation animation) {
120 | fab.setVisibility(View.INVISIBLE);
121 | if (callback != null) callback.onAnimationEnd();
122 | }
123 |
124 | @Override
125 | public void onAnimationRepeat(Animation animation) {
126 | //
127 | }
128 | });
129 | fab.startAnimation(anim);
130 | }
131 | }
132 |
133 | public interface ScaleCallback {
134 | public void onAnimationStart();
135 |
136 | public void onAnimationEnd();
137 | }
138 |
139 |
140 | }
141 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/Helper.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu;
2 |
3 | /**
4 | * Created by naman on 18/03/15.
5 | */
6 |
7 | import android.graphics.drawable.Drawable;
8 | import android.os.Build;
9 | import android.view.View;
10 |
11 | public class Helper {
12 |
13 | @SuppressWarnings("deprecation")
14 | public static void setBackground(View view, Drawable d) {
15 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
16 | view.setBackground(d);
17 | } else {
18 | view.setBackgroundDrawable(d);
19 | }
20 | }
21 |
22 | public static void postInvalidateOnAnimation(View view) {
23 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
24 | view.postInvalidateOnAnimation();
25 | } else {
26 | view.invalidate();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu;
2 |
3 | import android.app.FragmentManager;
4 | import android.content.DialogInterface;
5 | import android.content.SharedPreferences;
6 | import android.content.res.TypedArray;
7 | import android.graphics.Color;
8 | import android.graphics.Point;
9 | import android.os.Bundle;
10 | import android.os.Handler;
11 | import android.preference.PreferenceManager;
12 | import android.support.design.widget.FloatingActionButton;
13 | import android.support.v7.app.AppCompatActivity;
14 | import android.support.v7.widget.Toolbar;
15 | import android.util.TypedValue;
16 | import android.view.Display;
17 | import android.view.View;
18 |
19 |
20 | public class MainActivity extends AppCompatActivity implements DialogInterface.OnDismissListener {
21 |
22 |
23 | private CircularRevealView revealView;
24 | private View selectedView;
25 | private int backgroundColor;
26 | int maxX, maxY;
27 | android.os.Handler handler;
28 | private FloatingActionButton fabPower;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 |
33 | SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
34 |
35 | if (preferences.getString("pref_theme", "light").equals("dark"))
36 | setTheme(R.style.ThemeBaseDark);
37 |
38 | super.onCreate(savedInstanceState);
39 | setContentView(R.layout.activity_main);
40 |
41 | final Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
42 | setSupportActionBar(mToolbar);
43 | getSupportActionBar().setTitle("Material Power Menu");
44 |
45 | fabPower = (FloatingActionButton) findViewById(R.id.fab);
46 | revealView = (CircularRevealView) findViewById(R.id.reveal);
47 | backgroundColor = Color.parseColor("#11303030");
48 |
49 | if (preferences.getBoolean("pref_autolaunch", true)) {
50 | View v = fabPower;
51 | launchPowerMenu(v);
52 | }
53 |
54 | android.preference.PreferenceFragment fragment = new PreferenceFragment();
55 | android.app.FragmentManager fragmentManager = getFragmentManager();
56 | fragmentManager.beginTransaction()
57 | .replace(R.id.pref_container, fragment).commit();
58 |
59 | fabPower.setOnClickListener(new View.OnClickListener() {
60 | @Override
61 | public void onClick(View v) {
62 | launchPowerMenu(v);
63 | }
64 | });
65 |
66 | Display mdisp = getWindowManager().getDefaultDisplay();
67 | Point mdispSize = new Point();
68 | mdisp.getSize(mdispSize);
69 | maxX = mdispSize.x;
70 | maxY = mdispSize.y;
71 |
72 |
73 | }
74 |
75 | private Point getLocationInView(View src, View target) {
76 | final int[] l0 = new int[2];
77 | src.getLocationOnScreen(l0);
78 |
79 | final int[] l1 = new int[2];
80 | target.getLocationOnScreen(l1);
81 |
82 | l1[0] = l1[0] - l0[0] + target.getWidth() / 2;
83 | l1[1] = l1[1] - l0[1] + target.getHeight() / 2;
84 |
85 | return new Point(l1[0], l1[1]);
86 | }
87 |
88 |
89 | public void revealFromTop() {
90 | final int color = getBackgroundColor();
91 |
92 | final Point p = new Point(maxX / 2, maxY / 2);
93 |
94 | revealView.reveal(p.x, p.y, color, fabPower.getHeight() / 2, 440, null);
95 |
96 | }
97 |
98 | private void launchPowerMenu(View v) {
99 | final int color = getPrimaryColor();
100 | final Point p = getLocationInView(revealView, v);
101 |
102 | revealView.reveal(p.x, p.y, color, v.getHeight() / 2, 370, null);
103 | selectedView = v;
104 |
105 | FabAnimationUtils.scaleOut(fabPower, new FabAnimationUtils.ScaleCallback() {
106 | @Override
107 | public void onAnimationStart() {
108 |
109 | }
110 |
111 | @Override
112 | public void onAnimationEnd() {
113 | fabPower.setImageResource(R.drawable.close);
114 | FabAnimationUtils.scaleIn(fabPower);
115 | }
116 | });
117 |
118 | handler = new Handler();
119 | handler.postDelayed(new Runnable() {
120 | @Override
121 | public void run() {
122 | showPowerDialog();
123 | }
124 | }, 160);
125 | }
126 |
127 | private void showPowerDialog() {
128 | FragmentManager fm = getFragmentManager();
129 | PowerDialog powerDialog = new PowerDialog();
130 | powerDialog.show(fm, "fragment_power");
131 |
132 | }
133 |
134 | @Override
135 | public void onDismiss(final DialogInterface dialog) {
136 | View v = fabPower;
137 | final Point p = getLocationInView(revealView, v);
138 |
139 | handler = new Handler();
140 | handler.postDelayed(new Runnable() {
141 | @Override
142 | public void run() {
143 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
144 | FabAnimationUtils.scaleOut(fabPower, new FabAnimationUtils.ScaleCallback() {
145 | @Override
146 | public void onAnimationStart() {
147 |
148 | }
149 |
150 | @Override
151 | public void onAnimationEnd() {
152 | fabPower.setImageResource(R.drawable.power);
153 | FabAnimationUtils.scaleIn(fabPower);
154 | }
155 | });
156 | }
157 | }, 300);
158 |
159 | }
160 |
161 | private int getPrimaryColor() {
162 | TypedValue typedValue = new TypedValue();
163 | TypedArray a = obtainStyledAttributes(typedValue.data, new int[]{R.attr.colorPrimary});
164 | int color = a.getColor(0, 0);
165 | a.recycle();
166 |
167 | return color;
168 | }
169 |
170 | private int getBackgroundColor() {
171 | TypedValue typedValue = new TypedValue();
172 | TypedArray a = obtainStyledAttributes(typedValue.data, new int[]{R.attr.windowBackground});
173 | int color = a.getColor(0, 0);
174 | a.recycle();
175 |
176 | return color;
177 | }
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/PowerDialog.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu;
2 |
3 | import android.app.Activity;
4 | import android.app.DialogFragment;
5 | import android.content.DialogInterface;
6 | import android.graphics.Color;
7 | import android.graphics.Point;
8 | import android.os.Bundle;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.view.Window;
13 | import android.view.WindowManager;
14 | import android.widget.FrameLayout;
15 | import android.widget.ImageView;
16 | import android.widget.LinearLayout;
17 | import android.widget.ProgressBar;
18 | import android.widget.TextView;
19 | import android.os.Handler;
20 | import android.os.Looper;
21 |
22 | import eu.chainfire.libsuperuser.Shell;
23 |
24 | public class PowerDialog extends DialogFragment {
25 |
26 | public PowerDialog() {
27 |
28 | }
29 |
30 | LinearLayout power, reboot, soft_reboot, recovery, bootloader, safemode;
31 | FrameLayout frame, frame2;
32 | private CircularRevealView revealView;
33 | private View selectedView;
34 | private int backgroundColor;
35 | ProgressBar progress;
36 | TextView status, status_detail;
37 |
38 | private static final String SHUTDOWN_BROADCAST
39 | = "am broadcast android.intent.action.ACTION_SHUTDOWN";
40 | private static final String SHUTDOWN = "reboot -p";
41 | private static final String REBOOT_CMD = "reboot";
42 | private static final String REBOOT_SOFT_REBOOT_CMD = "setprop ctl.restart zygote";
43 | private static final String REBOOT_RECOVERY_CMD = "reboot recovery";
44 | private static final String REBOOT_BOOTLOADER_CMD = "reboot bootloader";
45 | private static final String[] REBOOT_SAFE_MODE
46 | = new String[]{"setprop persist.sys.safemode 1", REBOOT_SOFT_REBOOT_CMD};
47 |
48 | private static final int BG_PRIO = android.os.Process.THREAD_PRIORITY_BACKGROUND;
49 | private static final int RUNNABLE_DELAY_MS = 1000;
50 |
51 |
52 | @Override
53 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
54 | Bundle savedInstanceState) {
55 | View view = inflater.inflate(R.layout.fragment_power, container, false);
56 |
57 | revealView = (CircularRevealView) view.findViewById(R.id.reveal);
58 | backgroundColor = Color.parseColor("#ffffff");
59 | power = (LinearLayout) view.findViewById(R.id.power);
60 | reboot = (LinearLayout) view.findViewById(R.id.reboot);
61 | soft_reboot = (LinearLayout) view.findViewById(R.id.soft_reboot);
62 | recovery = (LinearLayout) view.findViewById(R.id.recovery);
63 | bootloader = (LinearLayout) view.findViewById(R.id.bootloader);
64 | safemode = (LinearLayout) view.findViewById(R.id.safemode);
65 |
66 | frame = (FrameLayout) view.findViewById(R.id.frame);
67 | frame2 = (FrameLayout) view.findViewById(R.id.frame2);
68 |
69 | status = (TextView) view.findViewById(R.id.status);
70 | status_detail = (TextView) view.findViewById(R.id.status_detail);
71 |
72 | progress = (ProgressBar) view.findViewById(R.id.progress);
73 |
74 |
75 | progress.getIndeterminateDrawable().setColorFilter(
76 | Color.parseColor("#ffffff"),
77 | android.graphics.PorterDuff.Mode.SRC_IN);
78 |
79 | reboot.setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View v) {
82 | final int color = Color.parseColor("#3f51b5");
83 | final Point p = getLocationInView(revealView, v);
84 |
85 | if (selectedView == v) {
86 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
87 | selectedView = null;
88 | } else {
89 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
90 | selectedView = v;
91 | }
92 |
93 | ((MainActivity) getActivity()).revealFromTop();
94 | frame.setVisibility(View.GONE);
95 | frame2.setVisibility(View.VISIBLE);
96 |
97 | status.setText("Reboot");
98 | status_detail.setText("Rebooting...");
99 |
100 | new BackgroundThread(REBOOT_CMD).start();
101 | }
102 | });
103 | power.setOnClickListener(new View.OnClickListener() {
104 | @Override
105 | public void onClick(View v) {
106 | final int color = Color.parseColor("#d32f2f");
107 | final Point p = getLocationInView(revealView, v);
108 |
109 | if (selectedView == v) {
110 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
111 | selectedView = null;
112 | } else {
113 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
114 | selectedView = v;
115 | }
116 |
117 | ((MainActivity) getActivity()).revealFromTop();
118 | frame.setVisibility(View.GONE);
119 | frame2.setVisibility(View.VISIBLE);
120 |
121 | status.setText("Power Off");
122 | status_detail.setText("Shutting down...");
123 |
124 | new BackgroundThread(SHUTDOWN).start();
125 |
126 |
127 | }
128 | });
129 | soft_reboot.setOnClickListener(new View.OnClickListener() {
130 | @Override
131 | public void onClick(View v) {
132 | final int color = Color.parseColor("#e91e63");
133 | final Point p = getLocationInView(revealView, v);
134 |
135 | if (selectedView == v) {
136 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
137 | selectedView = null;
138 | } else {
139 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
140 | selectedView = v;
141 | }
142 |
143 | ((MainActivity) getActivity()).revealFromTop();
144 | frame.setVisibility(View.GONE);
145 | frame2.setVisibility(View.VISIBLE);
146 |
147 | status.setText("Soft Reboot");
148 | status_detail.setText("Rebooting...");
149 |
150 | new BackgroundThread(REBOOT_SOFT_REBOOT_CMD).start();
151 |
152 |
153 | }
154 | });
155 | recovery.setOnClickListener(new View.OnClickListener() {
156 | @Override
157 | public void onClick(View v) {
158 | final int color = Color.parseColor("#8bc34a");
159 | final Point p = getLocationInView(revealView, v);
160 |
161 | if (selectedView == v) {
162 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
163 | selectedView = null;
164 | } else {
165 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
166 | selectedView = v;
167 | }
168 |
169 | ((MainActivity) getActivity()).revealFromTop();
170 | frame.setVisibility(View.GONE);
171 | frame2.setVisibility(View.VISIBLE);
172 |
173 | status.setText("Reboot Recovery");
174 | status_detail.setText("Rebooting...");
175 |
176 | new BackgroundThread(REBOOT_RECOVERY_CMD).start();
177 |
178 |
179 | }
180 | });
181 | bootloader.setOnClickListener(new View.OnClickListener() {
182 | @Override
183 | public void onClick(View v) {
184 | final int color = Color.parseColor("#277b71");
185 | final Point p = getLocationInView(revealView, v);
186 |
187 | if (selectedView == v) {
188 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
189 | selectedView = null;
190 | } else {
191 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
192 | selectedView = v;
193 | }
194 |
195 | ((MainActivity) getActivity()).revealFromTop();
196 | frame.setVisibility(View.GONE);
197 | frame2.setVisibility(View.VISIBLE);
198 |
199 | status.setText("Reboot Bootloader");
200 | status_detail.setText("Rebooting...");
201 |
202 | new BackgroundThread(REBOOT_BOOTLOADER_CMD).start();
203 |
204 |
205 | }
206 | });
207 | safemode.setOnClickListener(new View.OnClickListener() {
208 | @Override
209 | public void onClick(View v) {
210 | final int color = Color.parseColor("#009688");
211 | final Point p = getLocationInView(revealView, v);
212 |
213 | if (selectedView == v) {
214 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
215 | selectedView = null;
216 | } else {
217 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
218 | selectedView = v;
219 | }
220 |
221 | ((MainActivity) getActivity()).revealFromTop();
222 | frame.setVisibility(View.GONE);
223 | frame2.setVisibility(View.VISIBLE);
224 |
225 | status.setText("Safe Mode");
226 | status_detail.setText("Rebooting...");
227 |
228 | new BackgroundThread(REBOOT_SAFE_MODE).start();
229 |
230 |
231 | }
232 | });
233 | getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
234 |
235 | TextDrawable drawable1 = TextDrawable.builder()
236 | .buildRound("P", Color.parseColor("#d32f2f"));
237 | ((ImageView) view.findViewById(R.id.ipower)).setImageDrawable(drawable1);
238 |
239 | TextDrawable drawable2 = TextDrawable.builder()
240 | .buildRound("S", Color.parseColor("#009688"));
241 | ((ImageView) view.findViewById(R.id.isafe)).setImageDrawable(drawable2);
242 |
243 | TextDrawable drawable3 = TextDrawable.builder()
244 | .buildRound("B", Color.parseColor("#009688"));
245 | ((ImageView) view.findViewById(R.id.ibootloader)).setImageDrawable(drawable3);
246 |
247 | TextDrawable drawable4 = TextDrawable.builder()
248 | .buildRound("R", Color.parseColor("#009688"));
249 | ((ImageView) view.findViewById(R.id.irecovery)).setImageDrawable(drawable4);
250 |
251 | TextDrawable drawable5 = TextDrawable.builder()
252 | .buildRound("S", Color.parseColor("#e91e63"));
253 | ((ImageView) view.findViewById(R.id.isoftreboot)).setImageDrawable(drawable5);
254 |
255 | TextDrawable drawable6 = TextDrawable.builder()
256 | .buildRound("R", Color.parseColor("#3f51b5"));
257 | ((ImageView) view.findViewById(R.id.ireboot)).setImageDrawable(drawable6);
258 |
259 |
260 | return view;
261 |
262 | }
263 |
264 | private static void setThreadPrio(int prio) {
265 | android.os.Process.setThreadPriority(prio);
266 | }
267 |
268 | private static class BackgroundThread extends Thread {
269 | private Object sCmd;
270 |
271 | private BackgroundThread(Object cmd) {
272 | this.sCmd = cmd;
273 | }
274 |
275 | @Override
276 | public void run() {
277 | super.run();
278 | setThreadPrio(BG_PRIO);
279 |
280 | if (sCmd == null)
281 | return;
282 |
283 | /**
284 | * Sending a system broadcast to notify apps and the system that we're going down
285 | * so that they write any outstanding data that might need to be flushed
286 | */
287 | Shell.SU.run(SHUTDOWN_BROADCAST);
288 |
289 | new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
290 | @Override
291 | public void run() {
292 | if (sCmd instanceof String)
293 | Shell.SU.run((String) sCmd);
294 | else if (sCmd instanceof String[])
295 | Shell.SU.run((String[]) sCmd);
296 | }
297 | }, RUNNABLE_DELAY_MS);
298 | }
299 | }
300 |
301 | @Override
302 | public void onStart() {
303 | super.onStart();
304 |
305 | Window window = getDialog().getWindow();
306 | WindowManager.LayoutParams windowParams = window.getAttributes();
307 | windowParams.dimAmount = 0.0f;
308 |
309 | window.setAttributes(windowParams);
310 | }
311 |
312 | @Override
313 | public void onDismiss(final DialogInterface dialog) {
314 | super.onDismiss(dialog);
315 | final Activity activity = getActivity();
316 | if (activity != null && activity instanceof DialogInterface.OnDismissListener) {
317 | ((DialogInterface.OnDismissListener) activity).onDismiss(dialog);
318 | }
319 | }
320 |
321 | private Point getLocationInView(View src, View target) {
322 | final int[] l0 = new int[2];
323 | src.getLocationOnScreen(l0);
324 |
325 | final int[] l1 = new int[2];
326 | target.getLocationOnScreen(l1);
327 |
328 | l1[0] = l1[0] - l0[0] + target.getWidth() / 2;
329 | l1[1] = l1[1] - l0[1] + target.getHeight() / 2;
330 |
331 | return new Point(l1[0], l1[1]);
332 | }
333 |
334 | @Override
335 | public void onActivityCreated(Bundle arg0) {
336 | super.onActivityCreated(arg0);
337 | getDialog().getWindow()
338 | .getAttributes().windowAnimations = R.style.DialogAnimation;
339 | }
340 |
341 |
342 | }
343 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/PreferenceFragment.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu;
2 |
3 | import android.content.Intent;
4 | import android.net.Uri;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.os.Looper;
8 | import android.preference.ListPreference;
9 | import android.preference.Preference;
10 | import android.widget.Toast;
11 |
12 | import com.naman14.powermenu.xposed.XposedMainActivity;
13 |
14 | import eu.chainfire.libsuperuser.Shell;
15 |
16 | /**
17 | * Created by naman on 16/11/15.
18 | */
19 | public class PreferenceFragment extends android.preference.PreferenceFragment {
20 |
21 | private Preference rootstatus, source, rate, share, shortcut, about;
22 | private ListPreference themePreference;
23 |
24 | private static final int BG_PRIO = android.os.Process.THREAD_PRIORITY_BACKGROUND;
25 |
26 | private String Urlgithub = "https://github.com/naman14/MaterialPowerMenu";
27 | private String Urlrate = "https://play.google.com/store/apps/details?id=com.naman14.powermenu";
28 | private String Urlapps = "https://play.google.com/store/apps/developer?id=Naman14";
29 |
30 |
31 | @Override
32 | public void onCreate(Bundle savedInstanceState) {
33 | super.onCreate(savedInstanceState);
34 |
35 | addPreferencesFromResource(R.xml.prefs);
36 |
37 | rootstatus = findPreference("root_status");
38 | themePreference = (ListPreference) findPreference("pref_theme");
39 |
40 | source = findPreference("source_github");
41 | source.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
42 | @Override
43 | public boolean onPreferenceClick(Preference preference) {
44 | Intent i = new Intent(Intent.ACTION_VIEW);
45 | i.setData(Uri.parse(Urlgithub));
46 | startActivity(i);
47 | return true;
48 | }
49 | });
50 |
51 | rate = findPreference("rate_app");
52 | rate.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
53 | @Override
54 | public boolean onPreferenceClick(Preference preference) {
55 | Intent i = new Intent(Intent.ACTION_VIEW);
56 | i.setData(Uri.parse(Urlrate));
57 | startActivity(i);
58 | return true;
59 | }
60 | });
61 |
62 | share = findPreference("share_app");
63 | share.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
64 | @Override
65 | public boolean onPreferenceClick(Preference preference) {
66 | Intent i = new Intent(Intent.ACTION_SEND);
67 | i.setType("text/plain");
68 | i.putExtra(Intent.EXTRA_SUBJECT, "Material Power Menu");
69 | String sAux = "\nCheck out this beautiful app to add rebooting functionality to your rooted android device\n\n";
70 | sAux = sAux + "https://play.google.com/store/apps/details?id=com.naman14.powermenu \n\n";
71 | i.putExtra(Intent.EXTRA_TEXT, sAux);
72 | startActivity(Intent.createChooser(i, "Choose one"));
73 | return true;
74 | }
75 | });
76 |
77 | shortcut = findPreference("pref_homescreen_shortcut");
78 | shortcut.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
79 | @Override
80 | public boolean onPreferenceClick(Preference preference) {
81 | addShortcut();
82 | return true;
83 | }
84 | });
85 |
86 | about = findPreference("pref_about_donate");
87 | about.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
88 | @Override
89 | public boolean onPreferenceClick(Preference preference) {
90 | Intent i = new Intent(Intent.ACTION_VIEW);
91 | i.setData(Uri.parse(Urlapps));
92 | startActivity(i);
93 | return true;
94 | }
95 | });
96 |
97 | new Thread(new Runnable() {
98 | @Override
99 | public void run() {
100 | setThreadPrio(BG_PRIO);
101 |
102 | if (Shell.SU.available()) {
103 | new Handler(Looper.getMainLooper()).post(new Runnable() {
104 | @Override
105 | public void run() {
106 | if (rootstatus != null) {
107 | rootstatus.setTitle("Root available");
108 |
109 | rootstatus.setSummary("Root is available. App should work fine");
110 | }
111 | }
112 | });
113 | }
114 | }
115 | }).start();
116 |
117 |
118 | themePreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
119 | @Override
120 | public boolean onPreferenceChange(Preference preference, Object newValue) {
121 | Intent i = getActivity().getBaseContext().getPackageManager().getLaunchIntentForPackage(getActivity().getBaseContext().getPackageName());
122 | i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
123 | startActivity(i);
124 | return true;
125 | }
126 | });
127 | }
128 |
129 | private static void setThreadPrio(int prio) {
130 | android.os.Process.setThreadPriority(prio);
131 | }
132 |
133 | private void addShortcut() {
134 | //Adding shortcut for MainActivity
135 | //on Home screen
136 | Intent shortcutIntent = new Intent(getActivity(),
137 | XposedMainActivity.class);
138 |
139 | shortcutIntent.setAction(Intent.ACTION_MAIN);
140 |
141 | Intent addIntent = new Intent();
142 | addIntent
143 | .putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
144 | addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Power Menu");
145 | addIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
146 | addIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
147 | addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
148 | Intent.ShortcutIconResource.fromContext(getActivity(),
149 | R.drawable.ic_reboot));
150 | addIntent
151 | .setAction("com.android.launcher.action.INSTALL_SHORTCUT");
152 | getActivity().getApplicationContext().sendBroadcast(addIntent);
153 | Toast.makeText(getActivity().getApplicationContext(), "Added Home Screen Shortcurt", Toast.LENGTH_SHORT).show();
154 | getActivity().finish();
155 |
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/TextDrawable.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu;
2 |
3 | import android.graphics.*;
4 | import android.graphics.drawable.ShapeDrawable;
5 | import android.graphics.drawable.shapes.OvalShape;
6 | import android.graphics.drawable.shapes.RectShape;
7 | import android.graphics.drawable.shapes.RoundRectShape;
8 |
9 | /**
10 | * @author amulya
11 | * @datetime 14 Oct 2014, 3:53 PM
12 | */
13 | public class TextDrawable extends ShapeDrawable {
14 |
15 | private final Paint textPaint;
16 | private final Paint borderPaint;
17 | private static final float SHADE_FACTOR = 0.9f;
18 | private final String text;
19 | private final int color;
20 | private final RectShape shape;
21 | private final int height;
22 | private final int width;
23 | private final int fontSize;
24 | private final float radius;
25 | private final int borderThickness;
26 |
27 | private TextDrawable(Builder builder) {
28 | super(builder.shape);
29 |
30 | // shape properties
31 | shape = builder.shape;
32 | height = builder.height;
33 | width = builder.width;
34 | radius = builder.radius;
35 |
36 | // text and color
37 | text = builder.toUpperCase ? builder.text.toUpperCase() : builder.text;
38 | color = builder.color;
39 |
40 | // text paint settings
41 | fontSize = builder.fontSize;
42 | textPaint = new Paint();
43 | textPaint.setColor(builder.textColor);
44 | textPaint.setAntiAlias(true);
45 | textPaint.setFakeBoldText(builder.isBold);
46 | textPaint.setStyle(Paint.Style.FILL);
47 | textPaint.setTypeface(builder.font);
48 | textPaint.setTextAlign(Paint.Align.CENTER);
49 | textPaint.setStrokeWidth(builder.borderThickness);
50 |
51 | // border paint settings
52 | borderThickness = builder.borderThickness;
53 | borderPaint = new Paint();
54 | borderPaint.setColor(getDarkerShade(color));
55 | borderPaint.setStyle(Paint.Style.STROKE);
56 | borderPaint.setStrokeWidth(borderThickness);
57 |
58 | // drawable paint color
59 | Paint paint = getPaint();
60 | paint.setColor(color);
61 |
62 | }
63 |
64 | private int getDarkerShade(int color) {
65 | return Color.rgb((int)(SHADE_FACTOR * Color.red(color)),
66 | (int)(SHADE_FACTOR * Color.green(color)),
67 | (int)(SHADE_FACTOR * Color.blue(color)));
68 | }
69 |
70 | @Override
71 | public void draw(Canvas canvas) {
72 | super.draw(canvas);
73 | Rect r = getBounds();
74 |
75 |
76 | // draw border
77 | if (borderThickness > 0) {
78 | drawBorder(canvas);
79 | }
80 |
81 | int count = canvas.save();
82 | canvas.translate(r.left, r.top);
83 |
84 | // draw text
85 | int width = this.width < 0 ? r.width() : this.width;
86 | int height = this.height < 0 ? r.height() : this.height;
87 | int fontSize = this.fontSize < 0 ? (Math.min(width, height) / 2) : this.fontSize;
88 | textPaint.setTextSize(fontSize);
89 | canvas.drawText(text, width / 2, height / 2 - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint);
90 |
91 | canvas.restoreToCount(count);
92 |
93 | }
94 |
95 | private void drawBorder(Canvas canvas) {
96 | RectF rect = new RectF(getBounds());
97 | rect.inset(borderThickness/2, borderThickness/2);
98 |
99 | if (shape instanceof OvalShape) {
100 | canvas.drawOval(rect, borderPaint);
101 | }
102 | else if (shape instanceof RoundRectShape) {
103 | canvas.drawRoundRect(rect, radius, radius, borderPaint);
104 | }
105 | else {
106 | canvas.drawRect(rect, borderPaint);
107 | }
108 | }
109 |
110 | @Override
111 | public void setAlpha(int alpha) {
112 | textPaint.setAlpha(alpha);
113 | }
114 |
115 | @Override
116 | public void setColorFilter(ColorFilter cf) {
117 | textPaint.setColorFilter(cf);
118 | }
119 |
120 | @Override
121 | public int getOpacity() {
122 | return PixelFormat.TRANSLUCENT;
123 | }
124 |
125 | @Override
126 | public int getIntrinsicWidth() {
127 | return width;
128 | }
129 |
130 | @Override
131 | public int getIntrinsicHeight() {
132 | return height;
133 | }
134 |
135 | public static IShapeBuilder builder() {
136 | return new Builder();
137 | }
138 |
139 | public static class Builder implements IConfigBuilder, IShapeBuilder, IBuilder {
140 |
141 | private String text;
142 |
143 | private int color;
144 |
145 | private int borderThickness;
146 |
147 | private int width;
148 |
149 | private int height;
150 |
151 | private Typeface font;
152 |
153 | private RectShape shape;
154 |
155 | public int textColor;
156 |
157 | private int fontSize;
158 |
159 | private boolean isBold;
160 |
161 | private boolean toUpperCase;
162 |
163 | public float radius;
164 |
165 | private Builder() {
166 | text = "";
167 | color = Color.GRAY;
168 | textColor = Color.WHITE;
169 | borderThickness = 0;
170 | width = -1;
171 | height = -1;
172 | shape = new RectShape();
173 | font = Typeface.create("sans-serif-light", Typeface.NORMAL);
174 | fontSize = -1;
175 | isBold = false;
176 | toUpperCase = false;
177 | }
178 |
179 | public IConfigBuilder width(int width) {
180 | this.width = width;
181 | return this;
182 | }
183 |
184 | public IConfigBuilder height(int height) {
185 | this.height = height;
186 | return this;
187 | }
188 |
189 | public IConfigBuilder textColor(int color) {
190 | this.textColor = color;
191 | return this;
192 | }
193 |
194 | public IConfigBuilder withBorder(int thickness) {
195 | this.borderThickness = thickness;
196 | return this;
197 | }
198 |
199 | public IConfigBuilder useFont(Typeface font) {
200 | this.font = font;
201 | return this;
202 | }
203 |
204 | public IConfigBuilder fontSize(int size) {
205 | this.fontSize = size;
206 | return this;
207 | }
208 |
209 | public IConfigBuilder bold() {
210 | this.isBold = true;
211 | return this;
212 | }
213 |
214 | public IConfigBuilder toUpperCase() {
215 | this.toUpperCase = true;
216 | return this;
217 | }
218 |
219 | @Override
220 | public IConfigBuilder beginConfig() {
221 | return this;
222 | }
223 |
224 | @Override
225 | public IShapeBuilder endConfig() {
226 | return this;
227 | }
228 |
229 | @Override
230 | public IBuilder rect() {
231 | this.shape = new RectShape();
232 | return this;
233 | }
234 |
235 | @Override
236 | public IBuilder round() {
237 | this.shape = new OvalShape();
238 | return this;
239 | }
240 |
241 | @Override
242 | public IBuilder roundRect(int radius) {
243 | this.radius = radius;
244 | float[] radii = {radius, radius, radius, radius, radius, radius, radius, radius};
245 | this.shape = new RoundRectShape(radii, null, null);
246 | return this;
247 | }
248 |
249 | @Override
250 | public TextDrawable buildRect(String text, int color) {
251 | rect();
252 | return build(text, color);
253 | }
254 |
255 | @Override
256 | public TextDrawable buildRoundRect(String text, int color, int radius) {
257 | roundRect(radius);
258 | return build(text, color);
259 | }
260 |
261 | @Override
262 | public TextDrawable buildRound(String text, int color) {
263 | round();
264 | return build(text, color);
265 | }
266 |
267 | @Override
268 | public TextDrawable build(String text, int color) {
269 | this.color = color;
270 | this.text = text;
271 | return new TextDrawable(this);
272 | }
273 | }
274 |
275 | public interface IConfigBuilder {
276 | public IConfigBuilder width(int width);
277 |
278 | public IConfigBuilder height(int height);
279 |
280 | public IConfigBuilder textColor(int color);
281 |
282 | public IConfigBuilder withBorder(int thickness);
283 |
284 | public IConfigBuilder useFont(Typeface font);
285 |
286 | public IConfigBuilder fontSize(int size);
287 |
288 | public IConfigBuilder bold();
289 |
290 | public IConfigBuilder toUpperCase();
291 |
292 | public IShapeBuilder endConfig();
293 | }
294 |
295 | public static interface IBuilder {
296 |
297 | public TextDrawable build(String text, int color);
298 | }
299 |
300 | public static interface IShapeBuilder {
301 |
302 | public IConfigBuilder beginConfig();
303 |
304 | public IBuilder rect();
305 |
306 | public IBuilder round();
307 |
308 | public IBuilder roundRect(int radius);
309 |
310 | public TextDrawable buildRect(String text, int color);
311 |
312 | public TextDrawable buildRoundRect(String text, int color, int radius);
313 |
314 | public TextDrawable buildRound(String text, int color);
315 | }
316 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/xposed/XposedDialog.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu.xposed;
2 |
3 | import android.app.Activity;
4 | import android.app.DialogFragment;
5 | import android.content.DialogInterface;
6 | import android.graphics.Color;
7 | import android.graphics.Point;
8 | import android.os.Bundle;
9 | import android.os.Handler;
10 | import android.os.Looper;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.view.Window;
15 | import android.view.WindowManager;
16 | import android.widget.FrameLayout;
17 | import android.widget.ImageView;
18 | import android.widget.LinearLayout;
19 | import android.widget.ProgressBar;
20 | import android.widget.TextView;
21 |
22 | import com.naman14.powermenu.CircularRevealView;
23 | import com.naman14.powermenu.R;
24 | import com.naman14.powermenu.TextDrawable;
25 |
26 | import eu.chainfire.libsuperuser.Shell;
27 |
28 | /**
29 | * Created by naman on 20/03/15.
30 | */
31 | public class XposedDialog extends DialogFragment {
32 |
33 | public XposedDialog() {
34 |
35 | }
36 |
37 | LinearLayout power, reboot, soft_reboot, recovery, bootloader, safemode;
38 | FrameLayout frame, frame2;
39 | private CircularRevealView revealView;
40 | private View selectedView;
41 | private int backgroundColor;
42 | ProgressBar progress;
43 | TextView status, status_detail;
44 |
45 | private static final String SHUTDOWN_BROADCAST
46 | = "am broadcast android.intent.action.ACTION_SHUTDOWN";
47 | private static final String SHUTDOWN = "reboot -p";
48 | private static final String REBOOT_CMD = "reboot";
49 | private static final String REBOOT_SOFT_REBOOT_CMD = "setprop ctl.restart zygote";
50 | private static final String REBOOT_RECOVERY_CMD = "reboot recovery";
51 | private static final String REBOOT_BOOTLOADER_CMD = "reboot bootloader";
52 | private static final String[] REBOOT_SAFE_MODE
53 | = new String[]{"setprop persist.sys.safemode 1", REBOOT_SOFT_REBOOT_CMD};
54 |
55 | private static final int BG_PRIO = android.os.Process.THREAD_PRIORITY_BACKGROUND;
56 | private static final int RUNNABLE_DELAY_MS = 1000;
57 |
58 |
59 | @Override
60 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
61 | Bundle savedInstanceState) {
62 | View view = inflater.inflate(R.layout.fragment_power, container, false);
63 |
64 |
65 | revealView = (CircularRevealView) view.findViewById(R.id.reveal);
66 | backgroundColor = Color.parseColor("#ffffff");
67 | power = (LinearLayout) view.findViewById(R.id.power);
68 | reboot = (LinearLayout) view.findViewById(R.id.reboot);
69 | soft_reboot = (LinearLayout) view.findViewById(R.id.soft_reboot);
70 | recovery = (LinearLayout) view.findViewById(R.id.recovery);
71 | bootloader = (LinearLayout) view.findViewById(R.id.bootloader);
72 | safemode = (LinearLayout) view.findViewById(R.id.safemode);
73 |
74 | frame = (FrameLayout) view.findViewById(R.id.frame);
75 | frame2 = (FrameLayout) view.findViewById(R.id.frame2);
76 |
77 | status = (TextView) view.findViewById(R.id.status);
78 | status_detail = (TextView) view.findViewById(R.id.status_detail);
79 |
80 | progress = (ProgressBar) view.findViewById(R.id.progress);
81 |
82 |
83 | progress.getIndeterminateDrawable().setColorFilter(
84 | Color.parseColor("#ffffff"),
85 | android.graphics.PorterDuff.Mode.SRC_IN);
86 |
87 | reboot.setOnClickListener(new View.OnClickListener() {
88 | @Override
89 | public void onClick(View v) {
90 | final int color = Color.parseColor("#3f51b5");
91 | final Point p = getLocationInView(revealView, v);
92 |
93 | if (selectedView == v) {
94 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
95 | selectedView = null;
96 | } else {
97 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
98 | selectedView = v;
99 | }
100 |
101 | ((XposedMainActivity) getActivity()).revealFromTop();
102 | frame.setVisibility(View.GONE);
103 | frame2.setVisibility(View.VISIBLE);
104 |
105 | status.setText("Reboot");
106 | status_detail.setText("Rebooting...");
107 |
108 | new BackgroundThread(REBOOT_CMD).start();
109 | }
110 | });
111 | power.setOnClickListener(new View.OnClickListener() {
112 | @Override
113 | public void onClick(View v) {
114 | final int color = Color.parseColor("#d32f2f");
115 | final Point p = getLocationInView(revealView, v);
116 |
117 | if (selectedView == v) {
118 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
119 | selectedView = null;
120 | } else {
121 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
122 | selectedView = v;
123 | }
124 |
125 | ((XposedMainActivity) getActivity()).revealFromTop();
126 | frame.setVisibility(View.GONE);
127 | frame2.setVisibility(View.VISIBLE);
128 |
129 | status.setText("Power Off");
130 | status_detail.setText("Shutting down...");
131 |
132 | new BackgroundThread(SHUTDOWN).start();
133 |
134 |
135 | }
136 | });
137 | soft_reboot.setOnClickListener(new View.OnClickListener() {
138 | @Override
139 | public void onClick(View v) {
140 | final int color = Color.parseColor("#e91e63");
141 | final Point p = getLocationInView(revealView, v);
142 |
143 | if (selectedView == v) {
144 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
145 | selectedView = null;
146 | } else {
147 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
148 | selectedView = v;
149 | }
150 |
151 | ((XposedMainActivity) getActivity()).revealFromTop();
152 | frame.setVisibility(View.GONE);
153 | frame2.setVisibility(View.VISIBLE);
154 |
155 | status.setText("Soft Reboot");
156 | status_detail.setText("Rebooting...");
157 |
158 | new BackgroundThread(REBOOT_SOFT_REBOOT_CMD).start();
159 |
160 |
161 | }
162 | });
163 | recovery.setOnClickListener(new View.OnClickListener() {
164 | @Override
165 | public void onClick(View v) {
166 | final int color = Color.parseColor("#8bc34a");
167 | final Point p = getLocationInView(revealView, v);
168 |
169 | if (selectedView == v) {
170 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
171 | selectedView = null;
172 | } else {
173 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
174 | selectedView = v;
175 | }
176 |
177 | ((XposedMainActivity) getActivity()).revealFromTop();
178 | frame.setVisibility(View.GONE);
179 | frame2.setVisibility(View.VISIBLE);
180 |
181 | status.setText("Reboot Recovery");
182 | status_detail.setText("Rebooting...");
183 |
184 | new BackgroundThread(REBOOT_RECOVERY_CMD).start();
185 |
186 |
187 | }
188 | });
189 | bootloader.setOnClickListener(new View.OnClickListener() {
190 | @Override
191 | public void onClick(View v) {
192 | final int color = Color.parseColor("#277b71");
193 | final Point p = getLocationInView(revealView, v);
194 |
195 | if (selectedView == v) {
196 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
197 | selectedView = null;
198 | } else {
199 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
200 | selectedView = v;
201 | }
202 |
203 | ((XposedMainActivity) getActivity()).revealFromTop();
204 | frame.setVisibility(View.GONE);
205 | frame2.setVisibility(View.VISIBLE);
206 |
207 | status.setText("Reboot Bootloader");
208 | status_detail.setText("Rebooting...");
209 |
210 | new BackgroundThread(REBOOT_BOOTLOADER_CMD).start();
211 |
212 |
213 | }
214 | });
215 | safemode.setOnClickListener(new View.OnClickListener() {
216 | @Override
217 | public void onClick(View v) {
218 | final int color = Color.parseColor("#009688");
219 | final Point p = getLocationInView(revealView, v);
220 |
221 | if (selectedView == v) {
222 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
223 | selectedView = null;
224 | } else {
225 | revealView.reveal(p.x / 2, p.y / 2, color, v.getHeight() / 2, 440, null);
226 | selectedView = v;
227 | }
228 |
229 | ((XposedMainActivity) getActivity()).revealFromTop();
230 | frame.setVisibility(View.GONE);
231 | frame2.setVisibility(View.VISIBLE);
232 |
233 | status.setText("Safe Mode");
234 | status_detail.setText("Rebooting...");
235 |
236 | new BackgroundThread(REBOOT_SAFE_MODE).start();
237 |
238 |
239 | }
240 | });
241 | getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
242 |
243 | TextDrawable drawable1 = TextDrawable.builder()
244 | .buildRound("P", Color.parseColor("#d32f2f"));
245 | ((ImageView) view.findViewById(R.id.ipower)).setImageDrawable(drawable1);
246 |
247 | TextDrawable drawable2 = TextDrawable.builder()
248 | .buildRound("S", Color.parseColor("#009688"));
249 | ((ImageView) view.findViewById(R.id.isafe)).setImageDrawable(drawable2);
250 |
251 | TextDrawable drawable3 = TextDrawable.builder()
252 | .buildRound("B", Color.parseColor("#009688"));
253 | ((ImageView) view.findViewById(R.id.ibootloader)).setImageDrawable(drawable3);
254 |
255 | TextDrawable drawable4 = TextDrawable.builder()
256 | .buildRound("R", Color.parseColor("#009688"));
257 | ((ImageView) view.findViewById(R.id.irecovery)).setImageDrawable(drawable4);
258 |
259 | TextDrawable drawable5 = TextDrawable.builder()
260 | .buildRound("S", Color.parseColor("#e91e63"));
261 | ((ImageView) view.findViewById(R.id.isoftreboot)).setImageDrawable(drawable5);
262 |
263 | TextDrawable drawable6 = TextDrawable.builder()
264 | .buildRound("R", Color.parseColor("#3f51b5"));
265 | ((ImageView) view.findViewById(R.id.ireboot)).setImageDrawable(drawable6);
266 |
267 |
268 | return view;
269 |
270 | }
271 |
272 | private static void setThreadPrio(int prio) {
273 | android.os.Process.setThreadPriority(prio);
274 | }
275 |
276 | private static class BackgroundThread extends Thread {
277 | private Object sCmd;
278 |
279 | private BackgroundThread(Object cmd) {
280 | this.sCmd = cmd;
281 | }
282 |
283 | @Override
284 | public void run() {
285 | super.run();
286 | setThreadPrio(BG_PRIO);
287 |
288 | if (sCmd == null)
289 | return;
290 |
291 | /**
292 | * Sending a system broadcast to notify apps and the system that we're going down
293 | * so that they write any outstanding data that might need to be flushed
294 | */
295 | Shell.SU.run(SHUTDOWN_BROADCAST);
296 |
297 | new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
298 | @Override
299 | public void run() {
300 | if (sCmd instanceof String)
301 | Shell.SU.run((String) sCmd);
302 | else if (sCmd instanceof String[])
303 | Shell.SU.run((String[]) sCmd);
304 | }
305 | }, RUNNABLE_DELAY_MS);
306 | }
307 | }
308 |
309 | @Override
310 | public void onStart() {
311 | super.onStart();
312 |
313 | Window window = getDialog().getWindow();
314 | WindowManager.LayoutParams windowParams = window.getAttributes();
315 | windowParams.dimAmount = 0.0f;
316 |
317 | window.setAttributes(windowParams);
318 | }
319 |
320 | @Override
321 | public void onDismiss(final DialogInterface dialog) {
322 | super.onDismiss(dialog);
323 | final Activity activity = getActivity();
324 | if (activity != null && activity instanceof DialogInterface.OnDismissListener) {
325 | ((DialogInterface.OnDismissListener) activity).onDismiss(dialog);
326 | }
327 | }
328 |
329 | private Point getLocationInView(View src, View target) {
330 | final int[] l0 = new int[2];
331 | src.getLocationOnScreen(l0);
332 |
333 | final int[] l1 = new int[2];
334 | target.getLocationOnScreen(l1);
335 |
336 | l1[0] = l1[0] - l0[0] + target.getWidth() / 2;
337 | l1[1] = l1[1] - l0[1] + target.getHeight() / 2;
338 |
339 | return new Point(l1[0], l1[1]);
340 | }
341 |
342 | @Override
343 | public void onActivityCreated(Bundle arg0) {
344 | super.onActivityCreated(arg0);
345 | getDialog().getWindow()
346 | .getAttributes().windowAnimations = R.style.DialogAnimation;
347 | }
348 |
349 |
350 | }
351 |
352 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/xposed/XposedMain.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu.xposed;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 |
6 | import de.robv.android.xposed.IXposedHookLoadPackage;
7 | import de.robv.android.xposed.IXposedHookZygoteInit;
8 | import de.robv.android.xposed.XC_MethodHook;
9 | import de.robv.android.xposed.XC_MethodReplacement;
10 | import de.robv.android.xposed.XposedBridge;
11 | import de.robv.android.xposed.XposedHelpers;
12 | import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
13 |
14 | /**
15 | * Created by naman on 20/03/15.
16 | */
17 | public class XposedMain implements IXposedHookLoadPackage, IXposedHookZygoteInit {
18 |
19 | public static final String PACKAGE_NAME = XposedMain.class.getPackage().getName();
20 |
21 | public static final String CLASS_GLOBAL_ACTIONS = "com.android.internal.policy.impl.GlobalActions";
22 | public static final String CLASS_GLOBAL_POWER_ACTIONS = "com.android.internal.policy.impl.GlobalActions.PowerAction";
23 |
24 | Context mContext;
25 | Context context;
26 |
27 |
28 | @Override
29 | public void initZygote(StartupParam startupParam) throws Throwable {
30 |
31 |
32 | }
33 |
34 |
35 | @Override
36 | public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
37 | if (lpparam.packageName.equals("com.naman14.powermenu"))
38 | XposedBridge.log("in myappfvjjvf");
39 | final Class> globalActionsClass = XposedHelpers.findClass(CLASS_GLOBAL_ACTIONS, lpparam.classLoader);
40 |
41 |
42 | XposedBridge.hookAllConstructors(globalActionsClass, new XC_MethodHook() {
43 | @Override
44 | protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
45 | mContext = (Context) param.args[0];
46 | }
47 | });
48 |
49 | XposedHelpers.findAndHookMethod(CLASS_GLOBAL_POWER_ACTIONS, lpparam.classLoader, "onPress", new XC_MethodReplacement() {
50 | @Override
51 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
52 |
53 | showDialog();
54 | return null;
55 | }
56 |
57 | });
58 |
59 |
60 | }
61 |
62 | private void showDialog() {
63 | if (mContext == null) {
64 |
65 | return;
66 | }
67 |
68 | try {
69 |
70 | context = mContext.createPackageContext(PACKAGE_NAME, Context.CONTEXT_IGNORE_SECURITY);
71 | Intent intent = new Intent(context, XposedMainActivity.class);
72 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
73 | intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
74 | intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
75 | context.startActivity(intent);
76 | } catch (Exception e) {
77 | XposedBridge.log(e);
78 | }
79 | }
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/naman14/powermenu/xposed/XposedMainActivity.java:
--------------------------------------------------------------------------------
1 | package com.naman14.powermenu.xposed;
2 |
3 | import android.app.Activity;
4 | import android.app.DialogFragment;
5 | import android.app.FragmentManager;
6 | import android.content.DialogInterface;
7 | import android.graphics.Color;
8 | import android.graphics.Point;
9 | import android.os.Bundle;
10 | import android.os.Handler;
11 | import android.view.Display;
12 |
13 | import com.naman14.powermenu.CircularRevealView;
14 | import com.naman14.powermenu.R;
15 |
16 | /**
17 | * Created by naman on 20/03/15.
18 | */
19 | public class XposedMainActivity extends Activity implements DialogInterface.OnDismissListener {
20 |
21 | private CircularRevealView revealView;
22 | private int backgroundColor;
23 | android.os.Handler handler;
24 | int maxX, maxY;
25 |
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_main_xposed);
31 |
32 | revealView = (CircularRevealView) findViewById(R.id.reveal);
33 |
34 | Display mdisp = getWindowManager().getDefaultDisplay();
35 | Point mdispSize = new Point();
36 | mdisp.getSize(mdispSize);
37 | maxX = mdispSize.x;
38 | maxY = mdispSize.y;
39 |
40 | final int color = Color.parseColor("#00bcd4");
41 | final Point p = new Point(maxX / 2, maxY / 2);
42 |
43 | handler = new Handler();
44 | handler.postDelayed(new Runnable() {
45 | @Override
46 | public void run() {
47 | revealView.reveal(p.x, p.y, color, 2, 440, null);
48 | }
49 | }, 500);
50 |
51 |
52 | handler = new Handler();
53 | handler.postDelayed(new Runnable() {
54 | @Override
55 | public void run() {
56 | showPowerDialog();
57 | }
58 | }, 800);
59 |
60 |
61 | }
62 |
63 | private void showPowerDialog() {
64 | FragmentManager fm = getFragmentManager();
65 | XposedDialog powerDialog = new XposedDialog();
66 | powerDialog.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.AppThemeDialog);
67 | powerDialog.show(fm, "fragment_power");
68 |
69 | }
70 |
71 | public void revealFromTop() {
72 | final int color = Color.parseColor("#ffffff");
73 |
74 | final Point p = new Point(maxX / 2, maxY / 2);
75 |
76 | revealView.reveal(p.x, p.y, color, 2, 440, null);
77 |
78 |
79 | }
80 |
81 | @Override
82 | public void onDismiss(final DialogInterface dialog) {
83 |
84 | final Point p = new Point(maxX / 2, maxY / 2);
85 |
86 | handler = new Handler();
87 | handler.postDelayed(new Runnable() {
88 | @Override
89 | public void run() {
90 | revealView.hide(p.x, p.y, backgroundColor, 0, 330, null);
91 | }
92 | }, 300);
93 | handler = new Handler();
94 | handler.postDelayed(new Runnable() {
95 | @Override
96 | public void run() {
97 | finish();
98 | overridePendingTransition(0, 0);
99 | }
100 | }, 500);
101 |
102 |
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/layout_controller_fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/layout_controller_push_up_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/layout_controller_scale.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/push_up_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/scale.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_down_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naman14/MaterialPowerMenu/fcbe1061fd8aa1692aabe10a6761189d878b336e/app/src/main/res/drawable-hdpi/close.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_reboot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naman14/MaterialPowerMenu/fcbe1061fd8aa1692aabe10a6761189d878b336e/app/src/main/res/drawable-hdpi/ic_reboot.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/power.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naman14/MaterialPowerMenu/fcbe1061fd8aa1692aabe10a6761189d878b336e/app/src/main/res/drawable-hdpi/power.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
13 |
14 |
22 |
23 |
27 |
28 |
29 |
30 |
35 |
36 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_xposed.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_power.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
18 |
19 |
23 |
24 |
25 |
34 |
35 |
40 |
41 |
49 |
50 |
51 |
52 |
61 |
62 |
67 |
68 |
76 |
77 |
78 |
79 |
88 |
89 |
94 |
95 |
100 |
101 |
109 |
110 |
116 |
117 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
139 |
140 |
141 |
148 |
149 |
160 |
161 |
169 |
170 |
179 |
180 |
181 |
192 |
193 |
201 |
202 |
211 |
212 |
213 |
224 |
225 |
233 |
234 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
258 |
259 |
265 |
266 |
271 |
272 |
276 |
277 |
278 |
286 |
287 |
291 |
292 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - Light
6 | - Dark
7 |
8 |
9 |
10 | - light
11 | - dark
12 | - black
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFF5F5F5
4 | #212121
5 | #000000
6 |
7 | #00BCD4
8 | #0097A7
9 | #FF4081
10 |
11 | #263238
12 | #21272b
13 | #FF4081
14 |
15 | #000000
16 | #000000
17 | #ffffff
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Power Menu
5 | Hello world!
6 | Settings
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
31 |
40 |
41 |
42 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/values/values.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 420
6 | 420
7 | 340
8 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
23 |
24 |
29 |
30 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
49 |
50 |
54 |
55 |
56 |
60 |
61 |
62 |
63 |
64 |
66 |
67 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.0.0-rc2'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naman14/MaterialPowerMenu/fcbe1061fd8aa1692aabe10a6761189d878b336e/demo.gif
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naman14/MaterialPowerMenu/fcbe1061fd8aa1692aabe10a6761189d878b336e/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 10 15:27:10 PDT 2013
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------