() {
55 | @Override
56 | public void accept(Long count) throws Exception {
57 |
58 | LockerService.startService(getBaseContext());
59 |
60 | System.out.println("每 3 秒采集一次数据... count = " + count);
61 | if (count > 0 && count % 18 == 0)
62 | System.out.println("保存数据到磁盘。 saveCount = " + (count / 18 - 1));
63 | }
64 | });
65 | }
66 |
67 | @Override
68 | public void stopWork(Intent intent, int flags, int startId) {
69 | stopService();
70 | }
71 |
72 | /**
73 | * 任务是否正在运行?
74 | *
75 | * @return 任务正在运行, true; 任务当前不在运行, false; 无法判断, 什么也不做, null.
76 | */
77 | @Override
78 | public Boolean isWorkRunning(Intent intent, int flags, int startId) {
79 | //若还没有取消订阅, 就说明任务仍在运行.
80 | return sDisposable != null && !sDisposable.isDisposed();
81 | }
82 |
83 | @Override
84 | public IBinder onBind(Intent intent, Void v) {
85 | return null;
86 | }
87 |
88 | @Override
89 | public void onServiceKilled(Intent rootIntent) {
90 | System.out.println("保存数据到磁盘。");
91 | }
92 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/spark/SparkManager.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.spark;
2 |
3 | import java.util.Random;
4 |
5 | import android.graphics.BlurMaskFilter;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.graphics.Point;
10 |
11 | public class SparkManager {
12 |
13 | // 画笔对象
14 | private Paint mSparkPaint;
15 |
16 | // 当前触摸位置
17 | private int X, Y;
18 |
19 | // 花火半径
20 | private float radius = 0;
21 |
22 | // 火花喷射距离
23 | private float mDistance = 0;
24 |
25 | // 当前喷射距离
26 | private float mCurDistance = 0;
27 |
28 | // 火花半径
29 | private static final float SPARK_RADIUS = 4.0F;
30 |
31 | // 火花外侧阴影大小
32 | private static final float BLUR_SIZE = 9.0F;
33 |
34 | // 每帧速度
35 | private static final float PER_SPEED_SEC = 1.0F;
36 |
37 | // 随机数
38 | private Random mRandom = new Random();
39 |
40 | // 火花的起始点,终点,塞贝儿曲线拐点1,塞贝儿曲线拐点2
41 | private Point start, end, c1, c2;
42 |
43 | // 是否是激活状态
44 | public boolean isActive = false;
45 |
46 | public SparkManager() {
47 | // 初始化画笔
48 | setSparkPaint();
49 | }
50 |
51 | public int[] drawSpark(Canvas canvas, int x, int y, int[] store) {
52 |
53 | this.X = x;
54 | this.Y = y;
55 | this.mCurDistance = store[0];
56 | this.mDistance = store[1];
57 |
58 | // 初始化火花
59 | if (mCurDistance == mDistance && isActive) {
60 | mDistance = getRandom(SparkView.WIDTH / 2, mRandom.nextInt(15)) + 1;
61 | mCurDistance = 0;
62 |
63 | start = new Point(X, Y);
64 | end = getRandomPoint(start.x, start.y, (int) mDistance);
65 | c1 = getRandomPoint(start.x, start.y, mRandom.nextInt(SparkView.WIDTH / 16));
66 | c2 = getRandomPoint(end.x, end.y, mRandom.nextInt(SparkView.WIDTH / 16));
67 | }
68 | // 恢复火花路径
69 | else {
70 | start.set(store[2], store[3]);
71 | end.set(store[4], store[5]);
72 | c1.set(store[6], store[7]);
73 | c2.set(store[8], store[9]);
74 | }
75 |
76 | // 更新火花路径
77 | updateSparkPath();
78 | // 计算塞贝儿曲线的当前点
79 | Point bezierPoint = CalculateBezierPoint(mCurDistance / mDistance, start, c1, c2, end);
80 | // 设置随机颜色
81 | mSparkPaint.setColor(Color.argb(mRandom.nextInt(128) + 128, mRandom.nextInt(128) + 128, mRandom.nextInt(128) + 128, mRandom.nextInt(128) + 128));
82 | // 画花火
83 | canvas.drawCircle(bezierPoint.x, bezierPoint.y, radius, mSparkPaint);
84 |
85 |
86 | // 重置火花状态
87 | if (mCurDistance == mDistance) {
88 | store[0] = 0;
89 | store[1] = 0;
90 | }
91 | // 保持花火的状态
92 | else {
93 | store[0] = (int) mCurDistance;
94 | store[1] = (int) mDistance;
95 | store[2] = (int) start.x;
96 | store[3] = (int) start.y;
97 | store[4] = (int) end.x;
98 | store[5] = (int) end.y;
99 | store[6] = (int) c1.x;
100 | store[7] = (int) c1.y;
101 | store[8] = (int) c2.x;
102 | store[9] = (int) c2.y;
103 | }
104 |
105 | return store;
106 | }
107 |
108 | /**
109 | * 更新火花路径
110 | */
111 | private void updateSparkPath() {
112 | mCurDistance += PER_SPEED_SEC;
113 | // 前半段
114 | if (mCurDistance < (mDistance / 2) && (mCurDistance != 0)) {
115 | radius = SPARK_RADIUS * (mCurDistance / (mDistance / 2));
116 | }
117 | // 后半段
118 | else if (mCurDistance > (mDistance / 2) && (mCurDistance < mDistance)) {
119 | radius = SPARK_RADIUS - SPARK_RADIUS * ((mCurDistance / (mDistance / 2)) - 1);
120 | }
121 | // 完成
122 | else if (mCurDistance >= mDistance) {
123 | mCurDistance = 0;
124 | mDistance = 0;
125 | radius = 0;
126 | }
127 | }
128 |
129 | /**
130 | * 根据基准点获取指定范围为半径的随机点
131 | */
132 | private Point getRandomPoint(int baseX, int baseY, int r) {
133 | if (r <= 0) {
134 | r = 1;
135 | }
136 | int x = mRandom.nextInt(r);
137 | int y = (int) Math.sqrt(r * r - x * x);
138 |
139 | x = baseX + getRandomPNValue(x);
140 | y = baseY + getRandomPNValue(y);
141 |
142 | return new Point(x, y);
143 | }
144 |
145 | /**
146 | * 根据range范围,和chance几率。返回一个随机值
147 | */
148 | private int getRandom(int range, int chance) {
149 | int num = 0;
150 | switch (chance) {
151 | case 0:
152 | num = mRandom.nextInt(range);
153 | break;
154 | default:
155 | num = mRandom.nextInt(range / 4);
156 | break;
157 | }
158 |
159 | return num;
160 | }
161 |
162 | /**
163 | * 获取随机正负数
164 | */
165 | private int getRandomPNValue(int value) {
166 | return mRandom.nextBoolean() ? value : 0 - value;
167 | }
168 |
169 | /**
170 | * 计算塞贝儿曲线
171 | *
172 | * @param t 时间,范围0-1
173 | * @param s 起始点
174 | * @param c1 拐点1
175 | * @param c2 拐点2
176 | * @param e 终点
177 | * @return 塞贝儿曲线在当前时间下的点
178 | */
179 | private Point CalculateBezierPoint(float t, Point s, Point c1, Point c2, Point e) {
180 | float u = 1 - t;
181 | float tt = t * t;
182 | float uu = u * u;
183 | float uuu = uu * u;
184 | float ttt = tt * t;
185 |
186 | Point p = new Point((int) (s.x * uuu), (int) (s.y * uuu));
187 | p.x += 3 * uu * t * c1.x;
188 | p.y += 3 * uu * t * c1.y;
189 | p.x += 3 * u * tt * c2.x;
190 | p.y += 3 * u * tt * c2.y;
191 | p.x += ttt * e.x;
192 | p.y += ttt * e.y;
193 |
194 | return p;
195 | }
196 |
197 | /**
198 | * 设置画笔
199 | */
200 | private void setSparkPaint() {
201 | this.mSparkPaint = new Paint();
202 | // 打开抗锯齿
203 | this.mSparkPaint.setAntiAlias(true);
204 | /*
205 | * 设置画笔样式为填充 Paint.Style.STROKE:描边 Paint.Style.FILL_AND_STROKE:描边并填充
206 | * Paint.Style.FILL:填充
207 | */
208 | this.mSparkPaint.setDither(true);
209 | this.mSparkPaint.setStyle(Paint.Style.FILL);
210 | // 设置外围模糊效果
211 | this.mSparkPaint.setMaskFilter(new BlurMaskFilter(BLUR_SIZE, BlurMaskFilter.Blur.SOLID));
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/spark/SparkView.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.spark;
2 |
3 | import java.util.Date;
4 | import java.util.Random;
5 |
6 | import android.annotation.SuppressLint;
7 | import android.app.Activity;
8 | import android.content.Context;
9 | import android.graphics.Canvas;
10 | import android.graphics.Color;
11 | import android.graphics.PixelFormat;
12 | import android.graphics.PorterDuff;
13 | import android.util.AttributeSet;
14 | import android.util.DisplayMetrics;
15 | import android.view.MotionEvent;
16 | import android.view.SurfaceHolder;
17 | import android.view.SurfaceView;
18 |
19 | public class SparkView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
20 |
21 | private SurfaceHolder mHolder;
22 |
23 | private Canvas mCanvas;
24 |
25 | private boolean isRun;
26 |
27 | private SparkManager sparkManager;
28 |
29 | // 当前触摸点X,Y坐标
30 | private double X, Y;
31 |
32 | // 屏幕宽高
33 | public static int WIDTH, HEIGHT;
34 |
35 | private Random random = new Random();
36 |
37 | public SparkView(Context context) {
38 | super(context);
39 | init();
40 | }
41 |
42 | public SparkView(Context context, AttributeSet attrs) {
43 | super(context, attrs);
44 | init();
45 | }
46 |
47 | public SparkView(Context context, AttributeSet attrs, int defStyleAttr) {
48 | super(context, attrs, defStyleAttr);
49 | init();
50 | }
51 |
52 |
53 | public void init() {
54 | // 关闭硬件加速
55 | /*setLayerType(LAYER_TYPE_SOFTWARE, null);*/
56 |
57 | //背景 透明
58 | this.setZOrderOnTop(true);
59 | this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
60 |
61 | // 设置视图宽高(像素)
62 | DisplayMetrics metric = new DisplayMetrics();
63 | ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metric);
64 | WIDTH = metric.widthPixels;
65 | HEIGHT = metric.heightPixels;
66 |
67 | // 火花管理器
68 | sparkManager = new SparkManager();
69 |
70 | mHolder = this.getHolder();
71 | mHolder.addCallback(this);
72 | }
73 |
74 |
75 | @Override
76 | public void run() {
77 |
78 | // 火花数组
79 | int[][] sparks = new int[400][10];
80 |
81 | Date date = null;
82 | while (isRun) {
83 | date = new Date();
84 | try {
85 | mCanvas = mHolder.lockCanvas(null);
86 | if (mCanvas != null) {
87 | synchronized (mHolder) {
88 | // 清屏
89 | mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
90 |
91 | // 循环绘制所有火花
92 | for (int[] n : sparks) {
93 | n = sparkManager.drawSpark(mCanvas, (int) X, (int) Y, n);
94 | }
95 |
96 | // 控制帧数
97 | Thread.sleep(Math.max(0, 10 - (new Date().getTime() - date.getTime())));
98 | }
99 | }
100 | } catch (Exception e) {
101 | e.printStackTrace();
102 | } finally {
103 | if (mCanvas != null) {
104 | mHolder.unlockCanvasAndPost(mCanvas);
105 | }
106 | }
107 | }
108 | }
109 |
110 |
111 | public void startSpark(float x, float y) {
112 | X = x;
113 | Y = y;
114 | }
115 |
116 | public void setActive(boolean isActive) {
117 | sparkManager.isActive = isActive;
118 | }
119 |
120 |
121 | @SuppressLint("ClickableViewAccessibility")
122 | @Override
123 | public boolean onTouchEvent(MotionEvent event) {
124 | switch (event.getPointerCount()) {
125 | // 单点触摸
126 | case 1:
127 | switch (event.getAction()) {
128 | case MotionEvent.ACTION_DOWN:
129 | case MotionEvent.ACTION_MOVE:
130 | sparkManager.isActive = true;
131 | X = event.getX();
132 | Y = event.getY();
133 | break;
134 | case MotionEvent.ACTION_UP:
135 | sparkManager.isActive = false;
136 | break;
137 | default:
138 | break;
139 | }
140 | break;
141 | }
142 |
143 | return true;
144 | }
145 |
146 | // Surface的大小发生改变时调用
147 | @Override
148 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
149 | /*drawBackgound(holder);*/
150 | }
151 |
152 | // Surface创建时激发,一般在这里调用画面的线程
153 | @Override
154 | public void surfaceCreated(SurfaceHolder holder) {
155 | isRun = true;
156 | new Thread(this).start();
157 | }
158 |
159 | // 销毁时激发,一般在这里将画面的线程停止、释放。
160 | @Override
161 | public void surfaceDestroyed(SurfaceHolder argholder0) {
162 | isRun = false;
163 | }
164 |
165 | private void drawBackgound(SurfaceHolder holder) {
166 | mCanvas = mHolder.lockCanvas();
167 | mCanvas.drawColor(Color.parseColor("#00000000"));
168 | mHolder.unlockCanvasAndPost(mCanvas);
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/task/ExecuteTask.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.task;
2 |
3 | import android.os.Looper;
4 |
5 | import java.io.Serializable;
6 | import java.util.Map;
7 |
8 |
9 | public abstract class ExecuteTask implements Runnable, Serializable {
10 |
11 | public static final int EXCUTE_TASK_ERROR = -1001;
12 | public static final int EXCUTE_TASK_RESPONSE_JSON = 10001;
13 | public static final int EXCUTE_TASK_RESPONSE_OBJECT = 10002;
14 |
15 | /**
16 | * 这个会自动生成,不用自己设置
17 | */
18 | protected int uniqueID;
19 | /**
20 | * 主要是用来初始化的时候传入参数,
21 | * 然后根据不用的参数来进行异步操作
22 | */
23 | @SuppressWarnings("rawtypes")
24 | protected Map taskParam;// 内容参数
25 | /**
26 | * 异步操作完成之后的状态,失败、成功 or 其他
27 | */
28 | protected int status;
29 | /**
30 | * 如果是网络请求,并且获取的数据是Json,
31 | * 则直接可以给此字段赋值,然后在回调中get Json数据
32 | */
33 | protected String json;
34 | /**
35 | * 这个是异步操作后,如果想把异步数据传到UI线程,
36 | * 则可以通过此字段赋值,然后再强转得到所要的数据
37 | */
38 | protected Object result;
39 |
40 | protected String md5Id;
41 |
42 | private boolean isMainThread = Looper.myLooper() == Looper.getMainLooper();
43 |
44 | public String getMd5Id() {
45 | return md5Id;
46 | }
47 |
48 | public void setMd5Id(String md5Id) {
49 | this.md5Id = md5Id;
50 | }
51 |
52 | public ExecuteTask() {
53 | }
54 |
55 | public int getUniqueID() {
56 | return uniqueID;
57 | }
58 |
59 | public void setUniqueID(int uniqueID) {
60 | this.uniqueID = uniqueID;
61 | }
62 |
63 | @SuppressWarnings("rawtypes")
64 | public Map getTaskParam() {
65 | return taskParam;
66 | }
67 |
68 | @SuppressWarnings("rawtypes")
69 | public void setTaskParam(Map taskParam) {
70 | this.taskParam = taskParam;
71 | }
72 |
73 | public int getStatus() {
74 | return status;
75 | }
76 |
77 | public void setStatus(int status) {
78 | this.status = status;
79 | }
80 |
81 | public String getJson() {
82 | return json;
83 | }
84 |
85 | public void setJson(String json) {
86 | this.json = json;
87 | }
88 |
89 | public Object getResult() {
90 | return result;
91 | }
92 |
93 | public void setResult(Object result) {
94 | this.result = result;
95 | }
96 |
97 |
98 | public boolean isMainThread() {
99 | /*return Looper.myLooper() == Looper.getMainLooper() ; //this is wrong */
100 | return isMainThread;
101 | }
102 |
103 |
104 | @Override
105 | public void run() {
106 | doTask();
107 | }
108 |
109 | /**
110 | * 专门用来执行耗时的操作,
111 | * 子类只需要继承此类,实现此方法,
112 | * 在这个方法中执行所有耗时的操作
113 | * 用ExecuteTaskManager进行执行,可以回调
114 | * 也可以不回调
115 | *
116 | * 在继承此类的时候 doTask
117 | * 只能return null(不再回调) or return this(会回调)
118 | *
119 | * return null(可以在里面做异步操作)
120 | *
121 | * @return
122 | */
123 | public abstract ExecuteTask doTask();
124 | }
125 |
126 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/task/ExecuteTaskManager.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.task;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 | import android.os.Message;
6 | import android.text.TextUtils;
7 |
8 | import com.socks.library.KLog;
9 |
10 | import java.util.concurrent.ConcurrentHashMap;
11 | import java.util.concurrent.ConcurrentLinkedQueue;
12 | import java.util.concurrent.ConcurrentSkipListSet;
13 | import java.util.concurrent.ExecutorService;
14 | import java.util.concurrent.Executors;
15 | import java.util.concurrent.ScheduledExecutorService;
16 | import java.util.concurrent.TimeUnit;
17 |
18 |
19 | public class ExecuteTaskManager implements Runnable {
20 |
21 | /**
22 | * 线程执行完事儿后默认的回调类型
23 | */
24 | private static final int COMMON_EXECUTE_TASK_TYPE = 0;
25 | /**
26 | * 线程开关
27 | */
28 | public volatile boolean isRunning = false;
29 | /**
30 | * 是否初始化完成的开关
31 | */
32 | private volatile boolean isHasInit = false;
33 | /**
34 | * 默认线程池的线程数量
35 | */
36 | private static final int DEFAULT_THREAD_NUM = 5;
37 | /**
38 | * 初始化时的线程数量
39 | */
40 | private volatile int threadNum = DEFAULT_THREAD_NUM;
41 | /**
42 | * 定义一个单线程的线程池,专门用来执行耗时且不需要回调的操作
43 | */
44 | private static ScheduledExecutorService singlePool = null;
45 | /**
46 | * 定义一个大小为5的线程池(这个我们比较适合多个图片下载时使用)
47 | */
48 | private static ExecutorService threadPool = null;
49 | /**
50 | * 任务执行队列
51 | */
52 | private static ConcurrentLinkedQueue allExecuteTask = null;
53 | /**
54 | * 回调接口列表
55 | */
56 | private static ConcurrentHashMap uniqueListenerList = null;
57 | /**
58 | * Md5过滤接口列表
59 | */
60 | private static ConcurrentSkipListSet md5FilterList = null;
61 |
62 |
63 | public Handler getHandler() {
64 | return handler;
65 | }
66 |
67 | public int getThreadNum() {
68 | return threadNum;
69 | }
70 |
71 | public boolean isHasInit() {
72 | return isHasInit;
73 | }
74 |
75 | public boolean isRunning() {
76 | return isRunning;
77 | }
78 |
79 |
80 | /**
81 | * @author Rocky
82 | * @desc 得到普通的 ExecuteTask 对象,
83 | * 对外界开放的回调接口
84 | */
85 | public interface GetExecuteTaskCallback {
86 | void onDataLoaded(ExecuteTask task);
87 | }
88 |
89 |
90 | /**
91 | * 直接把数据发送到主线程
92 | */
93 | private final static Handler handler = new Handler(Looper.getMainLooper()) {
94 | @Override
95 | public void handleMessage(Message msg) {
96 | long start = System.currentTimeMillis();
97 |
98 | switch (msg.what) {
99 | case COMMON_EXECUTE_TASK_TYPE:
100 | if (msg.obj != null && msg.obj instanceof ExecuteTask) {
101 | ExecuteTaskManager.getInstance().doCommonHandler((ExecuteTask) msg.obj);
102 | } else {
103 | KLog.e("ExecuteTaskManager handler handleMessage 准备回调的对象不是 ExecuteTask, 回调失败");
104 | }
105 | break;
106 | /** 如果想要添加其他类型的回调,可以在此加入代码*/
107 | default:
108 | KLog.e("ExecuteTaskManager handler handleMessage 没有对应的What信息");
109 | break;
110 | }
111 | long end = System.currentTimeMillis();
112 |
113 | KLog.i("ExecuteTaskManager handleMessage 总共消耗时间为:" + (end - start));
114 | }
115 | };
116 |
117 |
118 | private static ExecuteTaskManager instance = null;
119 |
120 | private ExecuteTaskManager() {
121 | KLog.i("private ExecuteTaskManager() { 初始化 当前的线程Id为:" + Thread.currentThread().getId());
122 | /**
123 | * 防止在用户没有初始化的时候使用造成空指针
124 | */
125 | /*init();*/
126 | }
127 |
128 | public static ExecuteTaskManager getInstance() {
129 | if (instance == null) {
130 | synchronized (ExecuteTaskManager.class) {
131 | if (instance == null) {
132 | instance = new ExecuteTaskManager();
133 | }
134 | }
135 | }
136 | return instance;
137 | }
138 |
139 | /**
140 | * 初始化操作,这个主要是初始化需要执行异步
141 | * 回调任务的线程池,默认开启5个线程
142 | */
143 | public void init() {
144 | init(threadNum);
145 | }
146 |
147 | /**
148 | * 初始化操作,这个主要是初始化需要执行异步
149 | * 回调任务的线程池,可以传入线程的个数
150 | */
151 | public synchronized void init(int initNum) {
152 | if (!isHasInit) {
153 | /**
154 | * 初始化之后就相当于开始了线程次的运行
155 | * 只不过如果没有任务处于等待状态
156 | */
157 | isRunning = true;
158 | if (initNum > 0) {
159 | threadNum = initNum;
160 | }
161 | threadPool = Executors.newFixedThreadPool(threadNum);
162 | singlePool = Executors.newSingleThreadScheduledExecutor();
163 | allExecuteTask = new ConcurrentLinkedQueue<>();
164 | uniqueListenerList = new ConcurrentHashMap<>();
165 | md5FilterList = new ConcurrentSkipListSet<>();
166 | /**
167 | * 初始化需要用到的线程
168 | */
169 | for (int i = 0; i < threadNum; i++) {
170 | threadPool.execute(this);
171 | }
172 | isHasInit = true;
173 | } else {
174 | KLog.d("ExecuteTaskManager 已经初始化完成,不需要重复初始化");
175 | }
176 | }
177 |
178 |
179 | /**
180 | * 当应用被销毁时,执行清理操作
181 | */
182 | public void doDestroy() {
183 | /**
184 | * 关闭线程开关
185 | */
186 | isRunning = false;
187 | isHasInit = false;
188 | if (allExecuteTask != null) {
189 | allExecuteTask.clear();
190 | allExecuteTask = null;
191 | }
192 | if (uniqueListenerList != null) {
193 | uniqueListenerList.clear();
194 | uniqueListenerList = null;
195 | }
196 | if (md5FilterList != null) {
197 | md5FilterList.clear();
198 | md5FilterList = null;
199 | }
200 | if (threadPool != null) {
201 | threadPool.shutdown();
202 | threadPool = null;
203 | }
204 | if (singlePool != null) {
205 | singlePool.shutdown();
206 | singlePool = null;
207 | }
208 | }
209 |
210 | /**
211 | * 向任务队列中添加任务对象,添加成功后,
212 | * 任务会自动执行,执行完事儿后,不进行任何回调操作
213 | *
214 | * @param task 可执行的任务对象
215 | */
216 | public void newExecuteTask(ExecuteTask task) {
217 | if (task != null) {
218 | /**
219 | * 进行任务的过滤
220 | */
221 | if (!TextUtils.isEmpty(task.getMd5Id()) && md5FilterList.contains(task.getMd5Id())) {
222 | KLog.w("ExecuteTaskManager========newExecuteTask=====任务队列中已经有相同的任务了,被过滤,直接返回 " + task.toString());
223 | return;
224 | }
225 |
226 | allExecuteTask.offer(task);
227 | KLog.i("ExecuteTaskManager 添加任务成功之后" + "allExecuteTask.size()=" + allExecuteTask.size());
228 | long timeOne = System.currentTimeMillis();
229 | synchronized (allExecuteTask) {
230 | allExecuteTask.notifyAll();
231 | KLog.i("ExecuteTaskManager =====>处于唤醒状态");
232 | }
233 | long timeTwo = System.currentTimeMillis();
234 | KLog.i("ExecuteTaskManager唤醒线程所消耗的时间为:" + (timeTwo - timeOne));
235 | } else {
236 | KLog.w("ExecuteTaskManager====您添加的ExecuteTask为空,请重新添加");
237 | }
238 | }
239 |
240 | /**
241 | * 这个方法主要是获取普通的回调数据,
242 | * 获取成功后会把加入的 ExecuteTask 对象回调到用户界面
243 | *
244 | * @param task 加入的任务Task
245 | * @param callback 任务的回调接口GetDataCallback
246 | */
247 | public void getData(ExecuteTask task, GetExecuteTaskCallback callback) {
248 | /**
249 | * 把CallBack 接口加入列表中,用完之后移除
250 | */
251 | try {
252 | if (task != null && callback != null) {
253 |
254 | /**
255 | * 第一步任务的过滤
256 | */
257 | if (!TextUtils.isEmpty(task.getMd5Id()) && md5FilterList.contains(task.getMd5Id())) {
258 | KLog.w("ExecuteTaskManager========getData=====任务队列中已经有相同的任务了,被过滤,直接返回 " + task.toString());
259 | return;
260 | }
261 |
262 | /**
263 | * 第二步任务的过滤
264 | */
265 | if (task.getUniqueID() > 0 && uniqueListenerList.containsKey(task.getUniqueID())) {
266 | KLog.w("ExecuteTaskManager========getData=====uniqueListenerList任务队列中已经有相同的任务了,被过滤,直接返回 " + task.toString());
267 | return;
268 | }
269 |
270 |
271 | KLog.i("callback的hashcode为:" + callback.hashCode() + "task的hashcode为:" + task.hashCode() + " " + task.toString());
272 | if (task.getUniqueID() == 0) {
273 | task.setUniqueID(task.hashCode());
274 | }
275 | uniqueListenerList.put(task.getUniqueID(), callback);
276 |
277 | /**
278 | * 开始加入任务,执行任务
279 | */
280 | newExecuteTask(task);
281 | } else {
282 | KLog.w("Task 或者是 GetDataCallback 为空了,请检查你添加的参数!");
283 | }
284 | } catch (Exception e) {
285 | /**
286 | * 其实,这个地方的数据应该写到一个文件中
287 | */
288 | KLog.e("ExecuteTaskManager========getData====添加任务异常=====" + e.toString() + " thread id 为:" + Thread.currentThread().getId());
289 | e.printStackTrace();
290 | }
291 | }
292 |
293 | /**
294 | * 从任务队列中移除任务对象,使其不再执行(如果任务已经执行,则此方法无效)
295 | *
296 | * @param task 添加的任务对象
297 | */
298 | public void removeExecuteTask(ExecuteTask task) {
299 | if (task != null) {
300 | if (task.getUniqueID() > 0) {
301 | uniqueListenerList.remove(task.getUniqueID());
302 | }
303 | if (!TextUtils.isEmpty(task.getMd5Id())) {
304 | md5FilterList.remove(task.getMd5Id());
305 | }
306 | allExecuteTask.remove(task);
307 | } else {
308 | KLog.w("ExecuteTaskManager====您所要移除的任务为null,移除失败");
309 | }
310 | }
311 |
312 |
313 | /**
314 | * 清除所有的任务
315 | */
316 | public void removeAllExecuteTask() {
317 | allExecuteTask.clear();
318 | uniqueListenerList.clear();
319 | md5FilterList.clear();
320 | }
321 |
322 |
323 | /**=================================任务执行、回调、分发start============================================*/
324 |
325 | /**
326 | * 所有的异步任务都在此执行
327 | */
328 | @Override
329 | public void run() {
330 | while (isRunning) {
331 |
332 | KLog.i("ExecuteTaskManager====准备开始执行任务 总任务个数为 allExecuteTask.size()=" + allExecuteTask.size());
333 |
334 | /**
335 | * 从allExecuteTask取任务
336 | */
337 | ExecuteTask lastExecuteTask = allExecuteTask.poll();
338 |
339 | KLog.i("ExecuteTaskManager====从allExecuteTask取出了一个任务 allExecuteTask.size()=" + allExecuteTask.size());
340 | if (lastExecuteTask != null) {
341 | try {
342 | KLog.i("ExecuteTaskManager取出的任务ID" + lastExecuteTask.getUniqueID() + " " + lastExecuteTask.toString());
343 | /**
344 | * 真正开始执行任务,
345 | * 所有的耗时任务都是在子线程中执行
346 | */
347 | doExecuteTask(lastExecuteTask);
348 | } catch (Exception e) {
349 | KLog.e("ExecuteTaskManager=====>执行任务发生了异常,信息为:" + e.getMessage() + " " + lastExecuteTask.toString());
350 | e.printStackTrace();
351 |
352 | /**
353 | * 处理异常的回调==================start=====================
354 | */
355 | lastExecuteTask.setStatus(ExecuteTask.EXCUTE_TASK_ERROR);
356 | doSendMessage(lastExecuteTask);
357 | /**
358 | * 处理异常的回调==================end=====================
359 | */
360 | }
361 | KLog.i("任务仍在执行,ExecuteTaskManager线程处于运行状态,当前的线程的ID为:" + Thread.currentThread().getId());
362 | } else {
363 | KLog.i("任务执行完毕,ExecuteTaskManager线程处于等待状态,当前的线程的ID为:" + Thread.currentThread().getId());
364 | try {
365 | synchronized (allExecuteTask) {
366 | allExecuteTask.wait();
367 | }
368 | } catch (InterruptedException e) {
369 | KLog.e("ExecuteTaskManager=====> 线程等待时发生了错误,信息为:" + e.getMessage());
370 | e.printStackTrace();
371 | }
372 | }
373 | }
374 | }
375 |
376 |
377 | /**
378 | * 根据不同的ExecuteTask,执行相应的任务
379 | *
380 | * 这个是真正开始执行异步任务的地方,
381 | * 即调用需要在子线程执行的代码==>task.doTask()
382 | *
383 | * @param task ExecuteTask对象
384 | */
385 | private void doExecuteTask(ExecuteTask task) {
386 | if (task == null) {
387 | return;
388 | }
389 |
390 | long startTime = System.currentTimeMillis();
391 |
392 | ExecuteTask result = task.doTask();
393 |
394 | /**
395 | *
396 | * 开始执行的Task和最后得到的Task是同一个的时候,才会进行回调,
397 | * 否则不进行回调(保证在回调得到数据的时候知道是哪一个Task,以便进行强转)
398 | *
399 | *
400 | * 没有UniqueID相当于不需要回调
401 | *
402 | */
403 | if (result != null && task == result && result.getUniqueID() != 0) {
404 | doSendMessage(task);
405 | } else {
406 | KLog.w("doExecuteTask 耗时任务执行完毕,没有发生回调");
407 | if (task.getUniqueID() > 0) {
408 | uniqueListenerList.remove(task.getUniqueID());
409 | }
410 | if (!TextUtils.isEmpty(task.getMd5Id())) {
411 | md5FilterList.remove(task.getMd5Id());
412 | }
413 | }
414 | KLog.w("ExecuteTaskManager 执行任务" + task.toString() + " 耗时:" + (System.currentTimeMillis() - startTime));
415 | }
416 |
417 | /**
418 | * 把消息发送到相应的调用线程
419 | *
420 | * @param result 执行结果
421 | */
422 | private void doSendMessage(ExecuteTask result) {
423 | /**
424 | * 发送当前消息,更新UI(把数据回调到界面),
425 | * 下面不用做任何的发送消息,
426 | * 只在这一个地方发送就行,否者会发生错误!
427 | */
428 |
429 | KLog.w("doExecuteTask 耗时任务执行完毕,准备发生回调");
430 |
431 | if (result.isMainThread()) {
432 | Message msg = Message.obtain();
433 | msg.what = COMMON_EXECUTE_TASK_TYPE;
434 | msg.obj = result;
435 | handler.sendMessage(msg);
436 | } else {
437 | doCommonHandler(result);
438 | }
439 | }
440 |
441 | /**
442 | * 真正的回调操作,所有的任务在这里
443 | * 把数据回调到主界面
444 | *
445 | * @param task ExecuteTask对象
446 | */
447 | private void doCommonHandler(ExecuteTask task) {
448 | long start = System.currentTimeMillis();
449 | KLog.i("已经进入了private void doCommonHandler(Message msg) {");
450 |
451 | if (task != null) {
452 |
453 | try {
454 | if (uniqueListenerList.get(task.getUniqueID()) instanceof GetExecuteTaskCallback) {
455 | /**
456 | * 回调整个Task数据
457 | * 然后可以回调方法中去直接更新UI
458 | */
459 | ((GetExecuteTaskCallback) uniqueListenerList.get(task.getUniqueID())).onDataLoaded(task);
460 | KLog.i("ExecuteTaskManager========doCommonHandler=====回调成功====task 为:" + task.toString());
461 | } else {
462 | KLog.e("ExecuteTaskManager========doCommonHandler=====回调失败==if (task != null) { " + task.toString());
463 | }
464 | } catch (Exception e) {
465 | KLog.e("ExecuteTaskManager========doCommonHandler=====回调失败==if (task != null) { " + e.toString() + " " + task.toString());
466 | e.printStackTrace();
467 | }
468 |
469 | /**
470 | * 回调完成移除CallBack对象
471 | */
472 | if (task.getUniqueID() > 0) {
473 | uniqueListenerList.remove(task.getUniqueID());
474 | }
475 | if (!TextUtils.isEmpty(task.getMd5Id())) {
476 | md5FilterList.remove(task.getMd5Id());
477 | }
478 |
479 | } else {
480 | KLog.i("ExecuteTaskManager========doCommonHandler=====回调失败==已经移除了回调监听");
481 | }
482 | long end = System.currentTimeMillis();
483 | KLog.i("执行回调doCommonHandler 耗时:" + (end - start));
484 | }
485 | /**=================================任务执行、回调、分发end============================================*/
486 |
487 |
488 | /**=================================单线程池,可以顺序,延迟执行一些任务start============================================*/
489 |
490 | /**
491 | * 顺序执行耗时的操作
492 | *
493 | * @param runnable 对象
494 | */
495 | public void execute(Runnable runnable) {
496 | singlePool.execute(runnable);
497 | }
498 |
499 | /**
500 | * 顺序执行耗时的操作
501 | *
502 | * @param runnable 对象
503 | * @param delay 延迟执行的时间,单位毫秒
504 | */
505 | public void execute(Runnable runnable, long delay) {
506 | singlePool.schedule(runnable, delay, TimeUnit.MILLISECONDS);
507 | }
508 |
509 | /**
510 | * 顺序执行耗时的操作
511 | *
512 | * @param runnable 对象
513 | * @param delay 延迟执行的时间
514 | * @param timeUnit 时间单位
515 | */
516 | public void execute(Runnable runnable, long delay, TimeUnit timeUnit) {
517 | singlePool.schedule(runnable, delay, timeUnit);
518 | }
519 |
520 | public void scheduleAtFixedRate(Runnable runnable, long delay, long period, TimeUnit timeUnit) {
521 | singlePool.scheduleAtFixedRate(runnable, delay, period, timeUnit);
522 | }
523 |
524 | public void scheduleAtFixedRate(Runnable runnable, long delay, long period) {
525 | singlePool.scheduleAtFixedRate(runnable, delay, period, TimeUnit.MILLISECONDS);
526 | }
527 |
528 | public void scheduleAtFixedRate(Runnable runnable, long period) {
529 | singlePool.scheduleAtFixedRate(runnable, 0, period, TimeUnit.MILLISECONDS);
530 | }
531 |
532 | public ScheduledExecutorService getSinglePool() {
533 | return singlePool;
534 | }
535 | /**=================================单线程池,可以顺序,延迟执行一些任务end============================================*/
536 | }
537 |
538 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/util/DateUtils.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.util;
2 |
3 | import android.content.Context;
4 |
5 |
6 | import java.text.SimpleDateFormat;
7 | import java.util.Locale;
8 |
9 | /**
10 | * Start
11 | *
12 | * User:Rocky(email:1247106107@qq.com)
13 | * Created by Rocky on 2017/09/17 16:49
14 | * PACKAGE_NAME com.eagle.locker.util
15 | * PROJECT_NAME LockerScreen
16 | * TODO:
17 | * Description:
18 | *
19 | * Done
20 | */
21 | public class DateUtils {
22 | private static SimpleDateFormat sHourFormat24 = new SimpleDateFormat("HH:mm", Locale.getDefault());
23 | private static SimpleDateFormat sHourFormat12 = new SimpleDateFormat("hh:mm", Locale.getDefault());
24 |
25 | public static String getHourString(Context context, long time) {
26 | String strTimeFormat = android.provider.Settings.System.getString(context.getContentResolver(),
27 | android.provider.Settings.System.TIME_12_24);
28 | if (("12").equals(strTimeFormat)) {
29 | try {
30 | return sHourFormat12.format(time);
31 | } catch (Exception e) {
32 | }
33 | }
34 | return sHourFormat24.format(time);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/util/DimenUtils.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.util;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.util.TypedValue;
6 |
7 |
8 | /**
9 | * Start
10 | *
11 | * User:Rocky(email:1247106107@qq.com)
12 | * Created by Rocky on 2017/09/17 16:49
13 | * PACKAGE_NAME com.eagle.locker.util
14 | * PROJECT_NAME LockerScreen
15 | * TODO:
16 | * Description:
17 | *
18 | * Done
19 | */
20 | public class DimenUtils {
21 |
22 | private static final int DP_TO_PX = TypedValue.COMPLEX_UNIT_DIP;
23 | private static final int SP_TO_PX = TypedValue.COMPLEX_UNIT_SP;
24 | private static final int PX_TO_DP = TypedValue.COMPLEX_UNIT_MM + 1;
25 | private static final int PX_TO_SP = TypedValue.COMPLEX_UNIT_MM + 2;
26 | private static final int DP_TO_PX_SCALE_H = TypedValue.COMPLEX_UNIT_MM + 3;
27 | private static final int DP_SCALE_H = TypedValue.COMPLEX_UNIT_MM + 4;
28 | private static final int DP_TO_PX_SCALE_W = TypedValue.COMPLEX_UNIT_MM + 5;
29 |
30 |
31 | private static float applyDimension(Context context, int unit, float value, DisplayMetrics metrics) {
32 | switch (unit) {
33 | case DP_TO_PX:
34 | case SP_TO_PX:
35 | return TypedValue.applyDimension(unit, value, metrics);
36 | case PX_TO_DP:
37 | return value / metrics.density;
38 | case PX_TO_SP:
39 | return value / metrics.scaledDensity;
40 | case DP_TO_PX_SCALE_H:
41 | return TypedValue.applyDimension(DP_TO_PX, value * getScaleFactorH(context), metrics);
42 | case DP_SCALE_H:
43 | return value * getScaleFactorH(context);
44 | case DP_TO_PX_SCALE_W:
45 | return TypedValue.applyDimension(DP_TO_PX, value * getScaleFactorW(context), metrics);
46 | }
47 | return 0;
48 | }
49 |
50 | public static int dp2px(Context context, float value) {
51 | return (int) applyDimension(context, DP_TO_PX, value, context.getResources().getDisplayMetrics());
52 | }
53 |
54 | public static int sp2px(Context context, float value) {
55 | return (int) applyDimension(context, SP_TO_PX, value, context.getResources().getDisplayMetrics());
56 | }
57 |
58 | public static int px2dp(Context context, float value) {
59 | return (int) applyDimension(context, PX_TO_DP, value, context.getResources().getDisplayMetrics());
60 | }
61 |
62 | public static int px2sp(Context context, float value) {
63 | return (int) applyDimension(context, PX_TO_SP, value, context.getResources().getDisplayMetrics());
64 | }
65 |
66 | public static int dp2pxScaleW(Context context, float value) {
67 | return (int) applyDimension(context, DP_TO_PX_SCALE_W, value, context.getResources().getDisplayMetrics());
68 | }
69 |
70 | public static int dp2pxScaleH(Context context, float value) {
71 | return (int) applyDimension(context, DP_TO_PX_SCALE_H, value, context.getResources().getDisplayMetrics());
72 | }
73 |
74 | public static int dpScaleH(Context context, float value) {
75 | return (int) applyDimension(context, DP_SCALE_H, value, context.getResources().getDisplayMetrics());
76 | }
77 |
78 | public final static float BASE_SCREEN_WIDTH = 720f;
79 | public final static float BASE_SCREEN_HEIGHT = 1280f;
80 | public final static float BASE_SCREEN_DENSITY = 2f;
81 | public static Float sScaleW, sScaleH;
82 |
83 |
84 | /**
85 | * 如果要计算的值已经经过dip计算,则使用此结果,如果没有请使用getScaleFactorWithoutDip
86 | */
87 | public static float getScaleFactorW(Context context) {
88 | if (sScaleW == null) {
89 | sScaleW = (getScreenWidth(context) * BASE_SCREEN_DENSITY) / (getDensity(context) * BASE_SCREEN_WIDTH);
90 | }
91 | return sScaleW;
92 | }
93 |
94 | public static float getScaleFactorH(Context context) {
95 | if (sScaleH == null) {
96 | sScaleH = (getScreenHeight(context) * BASE_SCREEN_DENSITY)
97 | / (getDensity(context) * BASE_SCREEN_HEIGHT);
98 | }
99 | return sScaleH;
100 | }
101 |
102 | public static int getScreenWidth(Context context) {
103 | DisplayMetrics dm = context.getResources().getDisplayMetrics();
104 | return dm.widthPixels;
105 | }
106 |
107 | public static int getScreenHeight(Context context) {
108 | DisplayMetrics dm = context.getResources().getDisplayMetrics();
109 | return dm.heightPixels;
110 | }
111 |
112 | public static float getDensity(Context context) {
113 | return context.getResources().getDisplayMetrics().density;
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/util/PowerUtil.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.util;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.IntentFilter;
6 | import android.os.BatteryManager;
7 |
8 | /**
9 | * Start
10 | *
11 | * User:Rocky(email:1247106107@qq.com)
12 | * Created by Rocky on 2017/09/17 16:49
13 | * PACKAGE_NAME com.eagle.locker.util
14 | * PROJECT_NAME LockerScreen
15 | * TODO:
16 | * Description:
17 | *
18 | * Done
19 | */
20 | public class PowerUtil {
21 |
22 | public static boolean isCharging(Context context) {
23 | int status = getBatteryStatus(context, BatteryManager.EXTRA_STATUS, -1);
24 |
25 | return (status == BatteryManager.BATTERY_STATUS_CHARGING ||
26 | status == BatteryManager.BATTERY_STATUS_FULL);
27 | }
28 |
29 | public static int getLevel(Context context) {
30 | int level = getBatteryStatus(context, BatteryManager.EXTRA_LEVEL, 0);
31 | return level;
32 | }
33 |
34 | public static int getScale(Context context) {
35 | int scale = getBatteryStatus(context, BatteryManager.EXTRA_SCALE, -1);
36 | return scale;
37 | }
38 |
39 | private static int getBatteryStatus(Context context, String extraName, int defaultValue) {
40 | IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
41 | Intent batteryStatus = context.registerReceiver(null, intentFilter);
42 | if (batteryStatus == null) {
43 | return defaultValue;
44 | } else {
45 | return batteryStatus.getIntExtra(extraName, defaultValue);
46 | }
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/util/ViewUtils.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.util;
2 |
3 | import android.app.Activity;
4 | import android.view.View;
5 |
6 | /**
7 | * Start
8 | *
9 | * User:Rocky(email:1247106107@qq.com)
10 | * Created by Rocky on 2017/09/17 16:49
11 | * PACKAGE_NAME com.eagle.locker.util
12 | * PROJECT_NAME LockerScreen
13 | * TODO:
14 | * Description:
15 | *
16 | * Done
17 | */
18 | public class ViewUtils {
19 |
20 | @SuppressWarnings("unchecked")
21 | public static T get(View parent, int id) {
22 | if (parent == null) {
23 | return null;
24 | }
25 | return (T) parent.findViewById(id);
26 | }
27 |
28 | @SuppressWarnings("unchecked")
29 | public static T get(Activity activity, int id) {
30 | if (activity == null) {
31 | return null;
32 | }
33 | return (T) activity.findViewById(id);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/widget/RippleBackground.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.widget;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorSet;
5 | import android.animation.ObjectAnimator;
6 | import android.content.Context;
7 | import android.content.res.TypedArray;
8 | import android.graphics.Canvas;
9 | import android.graphics.Paint;
10 | import android.os.Build;
11 | import android.support.annotation.RequiresApi;
12 | import android.util.AttributeSet;
13 | import android.view.View;
14 | import android.view.animation.AccelerateDecelerateInterpolator;
15 | import android.widget.RelativeLayout;
16 |
17 |
18 | import com.eagle.locker.R;
19 |
20 | import java.util.ArrayList;
21 |
22 |
23 | /**
24 | * Start
25 | *
26 | * User:Rocky(email:1247106107@qq.com)
27 | * Created by Rocky on 2017/09/17 16:49
28 | * PACKAGE_NAME com.eagle.locker.widget
29 | * PROJECT_NAME LockerScreen
30 | * TODO:
31 | * Description:
32 | *
33 | * Done
34 | */
35 | public class RippleBackground extends RelativeLayout {
36 |
37 | private static final int DEFAULT_RIPPLE_COUNT = 6;
38 | private static final int DEFAULT_DURATION_TIME = 3000;
39 | private static final float DEFAULT_SCALE = 6.0f;
40 | private static final int DEFAULT_FILL_TYPE = 0;
41 |
42 | private int rippleColor;
43 | private float rippleStrokeWidth;
44 | private float rippleRadius;
45 | private int rippleDurationTime;
46 | private int rippleAmount;
47 | private int rippleDelay;
48 | private float rippleScale;
49 | private int rippleType;
50 | private Paint paint;
51 | private boolean animationRunning = false;
52 | private AnimatorSet animatorSet;
53 | private ArrayList animatorList;
54 | private LayoutParams rippleParams;
55 | private ArrayList rippleViewList = new ArrayList<>();
56 |
57 | public RippleBackground(Context context) {
58 | super(context);
59 | }
60 |
61 | public RippleBackground(Context context, AttributeSet attrs) {
62 | super(context, attrs);
63 | init(context, attrs);
64 | }
65 |
66 | public RippleBackground(Context context, AttributeSet attrs, int defStyleAttr) {
67 | super(context, attrs, defStyleAttr);
68 | init(context, attrs);
69 | }
70 |
71 | @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
72 | private void init(final Context context, final AttributeSet attrs) {
73 | if (isInEditMode())
74 | return;
75 |
76 | if (null == attrs) {
77 | throw new IllegalArgumentException("Attributes should be provided to this view,");
78 | }
79 |
80 | final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RippleBackground);
81 | rippleColor = typedArray.getColor(R.styleable.RippleBackground_rb_color, getResources().getColor(R.color.common_white));
82 | rippleStrokeWidth = typedArray.getDimension(R.styleable.RippleBackground_rb_strokeWidth, getResources().getDimension(R.dimen.rippleStrokeWidth));
83 | rippleRadius = typedArray.getDimension(R.styleable.RippleBackground_rb_radius, getResources().getDimension(R.dimen.rippleRadius));
84 | rippleDurationTime = typedArray.getInt(R.styleable.RippleBackground_rb_duration, DEFAULT_DURATION_TIME);
85 | rippleAmount = typedArray.getInt(R.styleable.RippleBackground_rb_rippleAmount, DEFAULT_RIPPLE_COUNT);
86 | rippleScale = typedArray.getFloat(R.styleable.RippleBackground_rb_scale, DEFAULT_SCALE);
87 | rippleType = typedArray.getInt(R.styleable.RippleBackground_rb_type, DEFAULT_FILL_TYPE);
88 | typedArray.recycle();
89 |
90 | rippleDelay = rippleDurationTime / rippleAmount;
91 |
92 | paint = new Paint();
93 | paint.setAntiAlias(true);
94 | if (rippleType == DEFAULT_FILL_TYPE) {
95 | rippleStrokeWidth = 0;
96 | paint.setStyle(Paint.Style.FILL);
97 | } else {
98 | paint.setStyle(Paint.Style.STROKE);
99 | }
100 | paint.setColor(rippleColor);
101 |
102 | rippleParams = new LayoutParams((int) (2 * (rippleRadius + rippleStrokeWidth)), (int) (2 * (rippleRadius + rippleStrokeWidth)));
103 | rippleParams.addRule(CENTER_IN_PARENT, TRUE);
104 |
105 | animatorSet = new AnimatorSet();
106 | animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
107 | animatorList = new ArrayList<>();
108 |
109 | for (int i = 0; i < rippleAmount; i++) {
110 | RippleView rippleView = new RippleView(getContext());
111 | addView(rippleView, rippleParams);
112 | rippleViewList.add(rippleView);
113 | final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(rippleView, "ScaleX", 1.0f, rippleScale);
114 | scaleXAnimator.setRepeatCount(ObjectAnimator.INFINITE);
115 | scaleXAnimator.setRepeatMode(ObjectAnimator.RESTART);
116 | scaleXAnimator.setStartDelay(i * rippleDelay);
117 | scaleXAnimator.setDuration(rippleDurationTime);
118 | animatorList.add(scaleXAnimator);
119 | final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(rippleView, "ScaleY", 1.0f, rippleScale);
120 | scaleYAnimator.setRepeatCount(ObjectAnimator.INFINITE);
121 | scaleYAnimator.setRepeatMode(ObjectAnimator.RESTART);
122 | scaleYAnimator.setStartDelay(i * rippleDelay);
123 | scaleYAnimator.setDuration(rippleDurationTime);
124 | animatorList.add(scaleYAnimator);
125 | final ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(rippleView, "Alpha", 0.1f, 1.0f, 0.4f, 0.1f);
126 | alphaAnimator.setRepeatCount(ObjectAnimator.INFINITE);
127 | alphaAnimator.setRepeatMode(ObjectAnimator.RESTART);
128 | alphaAnimator.setStartDelay(i * rippleDelay);
129 | alphaAnimator.setDuration(rippleDurationTime);
130 | animatorList.add(alphaAnimator);
131 | }
132 |
133 | animatorSet.playTogether(animatorList);
134 | }
135 |
136 | private class RippleView extends View {
137 |
138 | public RippleView(Context context) {
139 | super(context);
140 | this.setVisibility(View.INVISIBLE);
141 | }
142 |
143 | @Override
144 | protected void onDraw(Canvas canvas) {
145 | int radius = (Math.min(getWidth(), getHeight())) / 2;
146 | canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius - rippleStrokeWidth, paint);
147 | }
148 | }
149 |
150 | public void startRippleAnimation() {
151 | if (!isRippleAnimationRunning()) {
152 | for (RippleView rippleView : rippleViewList) {
153 | rippleView.setVisibility(VISIBLE);
154 | }
155 | animatorSet.start();
156 | animationRunning = true;
157 | }
158 | }
159 |
160 | public void stopRippleAnimation() {
161 | if (isRippleAnimationRunning()) {
162 | animatorSet.end();
163 | animationRunning = false;
164 | }
165 | }
166 |
167 | public boolean isRippleAnimationRunning() {
168 | return animationRunning;
169 | }
170 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/widget/SimpleAnimationListener.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.widget;
2 |
3 | import android.animation.Animator;
4 |
5 | /**
6 | * Start
7 | *
8 | * User:Rocky(email:1247106107@qq.com)
9 | * Created by Rocky on 2017/09/17 16:49
10 | * PACKAGE_NAME com.eagle.locker.widget
11 | * PROJECT_NAME LockerScreen
12 | * TODO:
13 | * Description:
14 | *
15 | * Done
16 | */
17 | public class SimpleAnimationListener implements Animator.AnimatorListener {
18 |
19 | @Override
20 | public void onAnimationStart(Animator animation) {
21 |
22 | }
23 |
24 | @Override
25 | public void onAnimationEnd(Animator animation) {
26 |
27 | }
28 |
29 | @Override
30 | public void onAnimationCancel(Animator animation) {
31 |
32 | }
33 |
34 | @Override
35 | public void onAnimationRepeat(Animator animation) {
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/widget/TouchPullDownView.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.widget;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.content.Context;
6 | import android.support.annotation.AttrRes;
7 | import android.support.annotation.NonNull;
8 | import android.support.annotation.Nullable;
9 | import android.util.AttributeSet;
10 | import android.view.LayoutInflater;
11 | import android.view.MotionEvent;
12 | import android.view.View;
13 | import android.view.animation.DecelerateInterpolator;
14 | import android.widget.FrameLayout;
15 | import android.widget.ImageView;
16 |
17 | import com.eagle.locker.R;
18 | import com.eagle.locker.util.DimenUtils;
19 |
20 | /**
21 | * Start
22 | *
23 | * User:Rocky(email:1247106107@qq.com)
24 | * Created by Rocky on 2017/09/17 16:49
25 | * PACKAGE_NAME com.eagle.locker.widget
26 | * PROJECT_NAME LockerScreen
27 | * TODO:
28 | * Description:
29 | *
30 | * Done
31 | */
32 | public class TouchPullDownView extends FrameLayout {
33 |
34 | private ImageView mLockLine;
35 |
36 | private boolean mIsMoving;
37 |
38 | private final static int TOUCH_STATE_REST = 0;
39 | private final static int TOUCH_STATE_SCROLLING = 1;
40 | private int mTouchState = TOUCH_STATE_REST;
41 | private float mDownMotionX;
42 | private float mDownMotionY;
43 |
44 | private int mTouchSlop = 10;
45 |
46 | private float moveDistance = 0;
47 | private float totalDistance = 0;
48 |
49 | public TouchPullDownView(@NonNull Context context) {
50 | super(context);
51 | init();
52 | }
53 |
54 | public TouchPullDownView(@NonNull Context context, @Nullable AttributeSet attrs) {
55 | super(context, attrs);
56 | init();
57 | }
58 |
59 | public TouchPullDownView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
60 | super(context, attrs, defStyleAttr);
61 | init();
62 | }
63 |
64 | private void init() {
65 | View view = LayoutInflater.from(getContext()).inflate(R.layout.touch_pull_down_view, this);
66 | mLockLine = (ImageView) view.findViewById(R.id.imgv_LockLine);
67 | totalDistance = DimenUtils.dp2px(getContext(), 240);
68 | }
69 |
70 |
71 | private boolean isInTouchArea(float motionX, float motionY) {
72 | if (motionX >= mLockLine.getX()
73 | && motionX <= mLockLine.getX() + mLockLine.getWidth()
74 | && motionY >= mLockLine.getY()
75 | && motionY <= mLockLine.getY() + mLockLine.getHeight()) {
76 | return true;
77 | }
78 | return false;
79 | }
80 |
81 | @Override
82 | public boolean onTouchEvent(MotionEvent event) {
83 |
84 | if (isAniming) {
85 | return true;
86 | }
87 |
88 | final int action = event.getAction();
89 | final float x = event.getX();
90 | final float y = event.getY();
91 |
92 |
93 | switch (action & MotionEvent.ACTION_MASK) {
94 | case MotionEvent.ACTION_DOWN:
95 | mIsMoving = false;
96 | mDownMotionX = x;
97 | mDownMotionY = y;
98 | mTouchState = TOUCH_STATE_REST;
99 | if (isInTouchArea(mDownMotionX, mDownMotionY)) {
100 | if (listener != null) {
101 | listener.onTouchGiftBoxArea();
102 | }
103 | return true;
104 | }
105 | break;
106 | case MotionEvent.ACTION_MOVE:
107 | if (mIsMoving || isInTouchArea(mDownMotionX, mDownMotionY)) {
108 | final int deltaX = (int) (x - mDownMotionX);
109 | final int deltaY = (int) (y - mDownMotionY);
110 | boolean isMoved = Math.abs(deltaX) > mTouchSlop || Math.abs(deltaY) > mTouchSlop;
111 |
112 | if (mTouchState == TOUCH_STATE_REST && isMoved) {
113 | mTouchState = TOUCH_STATE_SCROLLING;
114 | mIsMoving = true;
115 |
116 | }
117 |
118 | if (mTouchState == TOUCH_STATE_SCROLLING) {
119 | moveDistance = deltaY;
120 |
121 | if (moveDistance < totalDistance) {
122 | mLockLine.setTranslationY(moveDistance);
123 | }
124 |
125 | if (listener != null) {
126 | listener.onPullPercent(moveDistance / totalDistance);
127 | }
128 | return true;
129 | }
130 | }
131 | break;
132 | case MotionEvent.ACTION_CANCEL:
133 | case MotionEvent.ACTION_UP:
134 | if (mTouchState == TOUCH_STATE_SCROLLING) {
135 |
136 | startKickBackAnim(moveDistance < totalDistance ? moveDistance : totalDistance);
137 | mTouchState = TOUCH_STATE_REST;
138 | mDownMotionX = 0;
139 | mDownMotionY = 0;
140 | moveDistance = 0;
141 | return true;
142 | } else if (mTouchState == TOUCH_STATE_REST) {
143 | startPullDownAnim();
144 | }
145 | break;
146 | }
147 | return super.onTouchEvent(event);
148 | }
149 |
150 | private boolean isAniming;
151 |
152 | private void startPullDownAnim() {
153 | isAniming = true;
154 | ObjectAnimator pullDownAnim = ObjectAnimator.ofFloat(mLockLine, View.TRANSLATION_Y, 0, DimenUtils.dp2px(getContext(), 80), -80, 0, 40, 0, -20, 0);
155 | pullDownAnim.setRepeatCount(0);
156 | pullDownAnim.setDuration(500);
157 | pullDownAnim.setInterpolator(new DecelerateInterpolator());
158 | pullDownAnim.addListener(new SimpleAnimationListener() {
159 | @Override
160 | public void onAnimationEnd(Animator animation) {
161 | super.onAnimationEnd(animation);
162 | isAniming = false;
163 | if (listener != null) {
164 | listener.onGiftBoxClick();
165 | }
166 | }
167 | });
168 | pullDownAnim.start();
169 | }
170 |
171 | private void startKickBackAnim(final float distance) {
172 | isAniming = true;
173 | ObjectAnimator kickBackAnim = ObjectAnimator.ofFloat(mLockLine, View.TRANSLATION_Y, distance, -distance / 2, 0, distance / 4, 0, -distance / 8, 0);
174 | kickBackAnim.setRepeatCount(0);
175 | kickBackAnim.setDuration(500);
176 | kickBackAnim.setInterpolator(new DecelerateInterpolator());
177 | kickBackAnim.addListener(new SimpleAnimationListener() {
178 | @Override
179 | public void onAnimationEnd(Animator animation) {
180 | super.onAnimationEnd(animation);
181 | isAniming = false;
182 | if (listener != null) {
183 | if (distance > DimenUtils.dp2px(getContext(), 20)) {
184 | listener.onGiftBoxPulled();
185 | } else {
186 | listener.onPullCanceled();
187 | }
188 | }
189 | }
190 | });
191 | kickBackAnim.start();
192 | }
193 |
194 |
195 | private OnTouchPullDownListener listener;
196 |
197 | public void setOnTouchPullDownListener(OnTouchPullDownListener listener) {
198 | this.listener = listener;
199 | }
200 |
201 | public interface OnTouchPullDownListener {
202 | void onTouchGiftBoxArea();
203 |
204 | void onPullPercent(float percent);
205 |
206 | void onGiftBoxPulled();
207 |
208 | void onPullCanceled();
209 |
210 | void onGiftBoxClick();
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/app/src/main/java/com/eagle/locker/widget/TouchToUnLockView.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.support.annotation.AttrRes;
8 | import android.support.annotation.NonNull;
9 | import android.support.annotation.Nullable;
10 | import android.util.AttributeSet;
11 | import android.view.LayoutInflater;
12 | import android.view.MotionEvent;
13 | import android.view.View;
14 | import android.widget.FrameLayout;
15 | import android.widget.TextView;
16 |
17 | import com.eagle.locker.R;
18 | import com.eagle.locker.util.DimenUtils;
19 |
20 | /**
21 | * Start
22 | *
23 | * User:Rocky(email:1247106107@qq.com)
24 | * Created by Rocky on 2017/09/17 16:49
25 | * PACKAGE_NAME com.eagle.locker.widget
26 | * PROJECT_NAME LockerScreen
27 | * TODO:
28 | * Description:
29 | *
30 | * Done
31 | */
32 | public class TouchToUnLockView extends FrameLayout {
33 |
34 | private RippleBackground mLockRipple;
35 | private View mUnLockContainer;
36 | private TextView mUnlockTips;
37 |
38 | private boolean mIsMoving;
39 |
40 | private final static int TOUCH_STATE_REST = 0;
41 | private final static int TOUCH_STATE_SCROLLING = 1;
42 | private int mTouchState = TOUCH_STATE_REST;
43 | private float mDownMotionX;
44 | private float mDownMotionY;
45 |
46 | private int mTouchSlop = 10;
47 |
48 | private Paint circlePaint = new Paint(); //draw circle paint
49 | private int circleRadius = 0;
50 |
51 | private int moveDistance = 0;
52 | private float unlockDistance = 0;
53 |
54 | public TouchToUnLockView(@NonNull Context context) {
55 | super(context);
56 | init();
57 | }
58 |
59 | public TouchToUnLockView(@NonNull Context context, @Nullable AttributeSet attrs) {
60 | super(context, attrs);
61 | init();
62 | }
63 |
64 | public TouchToUnLockView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
65 | super(context, attrs, defStyleAttr);
66 | init();
67 | }
68 |
69 | private void init() {
70 | setWillNotDraw(false);
71 | View view = LayoutInflater.from(getContext()).inflate(R.layout.touch_to_unlock_view, this);
72 | mUnLockContainer = view.findViewById(R.id.fram_UnLockContainer);
73 | unlockDistance = (float) DimenUtils.getScreenWidth(getContext()) * 2 / 3;
74 | mLockRipple = (RippleBackground) view.findViewById(R.id.rb_LockRipple);
75 | mUnlockTips = (TextView) view.findViewById(R.id.txtv_UnlockTips);
76 | circleRadius = DimenUtils.dp2px(getContext(), 22) + 1;
77 |
78 | circlePaint.setAntiAlias(true);
79 | circlePaint.setStyle(Paint.Style.STROKE);
80 | circlePaint.setStrokeWidth(3);
81 | circlePaint.setColor(Color.WHITE);
82 | }
83 |
84 |
85 | public void startAnim() {
86 | mLockRipple.startRippleAnimation();
87 | }
88 |
89 | public void stopAnim() {
90 | mLockRipple.stopRippleAnimation();
91 | }
92 |
93 |
94 | @Override
95 | protected void onDraw(Canvas canvas) {
96 | super.onDraw(canvas);
97 |
98 | int circleRadius = getCircleRadius();
99 | canvas.drawCircle(mUnLockContainer.getX() + mUnLockContainer.getWidth() / 2, mUnLockContainer.getY() + mUnLockContainer.getHeight() / 2, circleRadius, circlePaint);
100 | }
101 |
102 | private boolean isInTouchUnlockArea(float motionX, float motionY) {
103 | if (motionX >= mUnLockContainer.getX()
104 | && motionX <= mUnLockContainer.getX() + mUnLockContainer.getWidth()
105 | && motionY >= mUnLockContainer.getY()
106 | && motionY <= mUnLockContainer.getY() + mUnLockContainer.getHeight()) {
107 | return true;
108 | }
109 | return false;
110 | }
111 |
112 | @Override
113 | public boolean onTouchEvent(MotionEvent event) {
114 | final int action = event.getAction();
115 | final float x = event.getX();
116 | final float y = event.getY();
117 | switch (action & MotionEvent.ACTION_MASK) {
118 | case MotionEvent.ACTION_DOWN:
119 | mIsMoving = false;
120 | mDownMotionX = x;
121 | mDownMotionY = y;
122 | mTouchState = TOUCH_STATE_REST;
123 | if (isInTouchUnlockArea(mDownMotionX, mDownMotionY)) {
124 | if (listener != null) {
125 | listener.onTouchLockArea();
126 | }
127 | mUnlockTips.setVisibility(VISIBLE);
128 | mUnlockTips.setText(R.string.slide_up_to_unlock);
129 | return true;
130 | }
131 | break;
132 | case MotionEvent.ACTION_MOVE:
133 | if (mIsMoving || isInTouchUnlockArea(mDownMotionX, mDownMotionY)) {
134 | final int deltaX = (int) (x - mDownMotionX);
135 | final int deltaY = (int) (y - mDownMotionY);
136 | boolean isMoved = Math.abs(deltaX) > mTouchSlop || Math.abs(deltaY) > mTouchSlop;
137 | if (mTouchState == TOUCH_STATE_REST && isMoved) {
138 | mTouchState = TOUCH_STATE_SCROLLING;
139 | mIsMoving = true;
140 | }
141 | if (mTouchState == TOUCH_STATE_SCROLLING) {
142 | moveDistance = countDistance(mDownMotionX, mDownMotionY, x, y);
143 | invalidate();
144 | if (listener != null) {
145 | listener.onSlidePercent(moveDistance / unlockDistance > 1 ? 1 : moveDistance / unlockDistance);
146 | }
147 | if (moveDistance > (unlockDistance * 2 / 3)) {
148 | mUnlockTips.setText(R.string.release_to_unlock);
149 | } else {
150 | mUnlockTips.setText(R.string.slide_up_to_unlock);
151 | }
152 | return true;
153 | }
154 | }
155 | break;
156 | case MotionEvent.ACTION_CANCEL:
157 | case MotionEvent.ACTION_UP:
158 | mUnlockTips.setVisibility(GONE);
159 | if (mTouchState == TOUCH_STATE_SCROLLING) {
160 | if (listener != null) {
161 | if (moveDistance > (unlockDistance * 2 / 3)) {
162 | listener.onSlideToUnlock();
163 | } else {
164 | listener.onSlideAbort();
165 | }
166 | }
167 | mTouchState = TOUCH_STATE_REST;
168 | mDownMotionX = 0;
169 | mDownMotionY = 0;
170 | moveDistance = 0;
171 | invalidate();
172 | return true;
173 | } else if (mTouchState == TOUCH_STATE_REST) {
174 | if (listener != null) {
175 | listener.onSlideAbort();
176 | }
177 | return true;
178 | }
179 | break;
180 | }
181 | return super.onTouchEvent(event);
182 | }
183 |
184 |
185 | private int getCircleRadius() {
186 | return circleRadius + moveDistance;
187 | }
188 |
189 |
190 | private int countDistance(float x1, float y1, float x2, float y2) {
191 | return (int) Math.sqrt((x2 -= x1) * x2 + (y2 -= y1) * y2);
192 | }
193 |
194 | private OnTouchToUnlockListener listener;
195 |
196 | public void setOnTouchToUnlockListener(OnTouchToUnlockListener listener) {
197 | this.listener = listener;
198 | }
199 |
200 | public interface OnTouchToUnlockListener {
201 | void onTouchLockArea();
202 |
203 | void onSlidePercent(float percent);
204 |
205 | void onSlideToUnlock();
206 |
207 | void onSlideAbort();
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex0.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex1.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex10.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex11.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex12.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex13.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex14.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex15.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex2.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex3.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex4.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex5.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex6.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex7.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex8.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/tex9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-nodpi/tex9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/common_lock_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xhdpi/common_lock_bg.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_charge_four.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xxhdpi/ic_lock_charge_four.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_charge_one.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xxhdpi/ic_lock_charge_one.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_charge_three.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xxhdpi/ic_lock_charge_three.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_charge_two.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xxhdpi/ic_lock_charge_two.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_cross_one.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xxhdpi/ic_lock_cross_one.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xxhdpi/ic_lock_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xxhdpi/ic_lock_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/drawable-xxhdpi/ic_lock_setting.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/common_sticker_header_bg_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/lock_battery_charging_30.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/lock_battery_charging_60.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/lock_battery_charging_90.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_locker.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
17 |
18 |
24 |
25 |
26 |
30 |
31 |
38 |
39 |
50 |
51 |
61 |
62 |
63 |
64 |
71 |
72 |
81 |
82 |
93 |
94 |
101 |
102 |
103 |
109 |
110 |
120 |
121 |
122 |
123 |
128 |
129 |
130 |
134 |
135 |
136 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/locker_setting_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/touch_pull_down_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/touch_to_unlock_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
20 |
21 |
22 |
29 |
30 |
42 |
43 |
44 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 锁屏
3 | 向上滑动解锁
4 | 松手解锁
5 | 下拉取消
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
28 |
29 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 | #FFFFFF
8 | #55000000
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 20dp
4 |
5 | 2dp
6 | 64dp
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/integers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 500
4 | 350
5 | 60
6 | 240
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Locker Screen
3 | Slide up To Unlock
4 | Release to Unlock
5 | Pull Canceled
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/com/eagle/locker/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.eagle.locker;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/art/img_locker_one.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/art/img_locker_one.gif
--------------------------------------------------------------------------------
/art/img_locker_two.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/art/img_locker_two.jpg
--------------------------------------------------------------------------------
/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:2.3.2'
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 | maven {
19 | url "https://jitpack.io"
20 | }
21 | maven {
22 | url "http://dl.bintray.com/piasy/maven"
23 | }
24 | }
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/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 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RockySteveJobs/LockerScreen/a6e38231682c39bdee961e503ff466f11d740735/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Jun 03 18:43:39 CST 2017
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-3.3-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 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------