() {
192 | @Override
193 | public PathRecord createFromParcel(Parcel source) {
194 | return new PathRecord(source);
195 | }
196 |
197 | @Override
198 | public PathRecord[] newArray(int size) {
199 | return new PathRecord[size];
200 | }
201 | };
202 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/bean/SportMotionRecord.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.bean;
2 |
3 | import java.io.Serializable;
4 |
5 | import io.realm.RealmObject;
6 | import io.realm.annotations.PrimaryKey;
7 | import io.realm.annotations.Required;
8 |
9 | /**
10 | * 描述: 用于记录一条轨迹,包括起点、终点、轨迹中间点、距离、耗时、时间
11 | * 作者: james
12 | * 日期: 2019/2/25 19:59
13 | * 类名: SportMotionRecord
14 | */
15 | public class SportMotionRecord extends RealmObject implements Serializable {
16 |
17 | /**
18 | * 表示该字段是主键
19 | *
20 | * 字段类型必须是字符串(String)或整数(byte,short,int或long)
21 | * 以及它们的包装类型(Byte,Short, Integer, 或 Long)。不可以存在多个主键,
22 | * 使用字符串字段作为主键意味着字段被索引(注释@PrimaryKey隐式地设置注释@Index)。
23 | */
24 | @PrimaryKey
25 | private Long id;
26 |
27 | //登录者ID
28 | // @Required
29 | private int master;
30 |
31 | //运动距离
32 | @Required
33 | private Double distance;
34 | //运动时长
35 | @Required
36 | private Long duration;
37 | //运动轨迹
38 | @Required
39 | private String pathLine;
40 | //运动开始点
41 | @Required
42 | private String stratPoint;
43 | //运动结束点
44 | @Required
45 | private String endPoint;
46 | //运动开始时间
47 | @Required
48 | private Long mStartTime;
49 | //运动结束时间
50 | @Required
51 | private Long mEndTime;
52 | //消耗卡路里
53 | @Required
54 | private Double calorie;
55 | //平均时速(公里/小时)
56 | @Required
57 | private Double speed;
58 | //平均配速(分钟/公里)
59 | @Required
60 | private Double distribution;
61 | //日期标记
62 | @Required
63 | private String dateTag;
64 |
65 | private String str1;//预留字段
66 | private String str2;//预留字段
67 | private String str3;//预留字段
68 |
69 | public Long getId() {
70 | return id;
71 | }
72 |
73 | public void setId(Long id) {
74 | this.id = id;
75 | }
76 |
77 | public int getMaster() {
78 | return master;
79 | }
80 |
81 | public void setMaster(int master) {
82 | this.master = master;
83 | }
84 |
85 | public Double getDistance() {
86 | return distance;
87 | }
88 |
89 | public void setDistance(Double distance) {
90 | this.distance = distance;
91 | }
92 |
93 | public Long getDuration() {
94 | return duration;
95 | }
96 |
97 | public void setDuration(Long duration) {
98 | this.duration = duration;
99 | }
100 |
101 | public String getPathLine() {
102 | return pathLine;
103 | }
104 |
105 | public void setPathLine(String pathLine) {
106 | this.pathLine = pathLine;
107 | }
108 |
109 | public String getStratPoint() {
110 | return stratPoint;
111 | }
112 |
113 | public void setStratPoint(String stratPoint) {
114 | this.stratPoint = stratPoint;
115 | }
116 |
117 | public String getEndPoint() {
118 | return endPoint;
119 | }
120 |
121 | public void setEndPoint(String endPoint) {
122 | this.endPoint = endPoint;
123 | }
124 |
125 | public Long getmStartTime() {
126 | return mStartTime;
127 | }
128 |
129 | public void setmStartTime(Long mStartTime) {
130 | this.mStartTime = mStartTime;
131 | }
132 |
133 | public Long getmEndTime() {
134 | return mEndTime;
135 | }
136 |
137 | public void setmEndTime(Long mEndTime) {
138 | this.mEndTime = mEndTime;
139 | }
140 |
141 | public Double getCalorie() {
142 | return calorie;
143 | }
144 |
145 | public void setCalorie(Double calorie) {
146 | this.calorie = calorie;
147 | }
148 |
149 | public Double getSpeed() {
150 | return speed;
151 | }
152 |
153 | public void setSpeed(Double speed) {
154 | this.speed = speed;
155 | }
156 |
157 | public Double getDistribution() {
158 | return distribution;
159 | }
160 |
161 | public void setDistribution(Double distribution) {
162 | this.distribution = distribution;
163 | }
164 |
165 | public String getDateTag() {
166 | return dateTag;
167 | }
168 |
169 | public void setDateTag(String dateTag) {
170 | this.dateTag = dateTag;
171 | }
172 |
173 | public String getStr1() {
174 | return str1;
175 | }
176 |
177 | public void setStr1(String str1) {
178 | this.str1 = str1;
179 | }
180 |
181 | public String getStr2() {
182 | return str2;
183 | }
184 |
185 | public void setStr2(String str2) {
186 | this.str2 = str2;
187 | }
188 |
189 | public String getStr3() {
190 | return str3;
191 | }
192 |
193 | public void setStr3(String str3) {
194 | this.str3 = str3;
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/bean/TabEntity.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.bean;
2 |
3 | import com.flyco.tablayout.listener.CustomTabEntity;
4 |
5 | public class TabEntity implements CustomTabEntity {
6 | public String title;
7 | public int selectedIcon;
8 | public int unSelectedIcon;
9 |
10 | public TabEntity(String title, int selectedIcon, int unSelectedIcon) {
11 | this.title = title;
12 | this.selectedIcon = selectedIcon;
13 | this.unSelectedIcon = unSelectedIcon;
14 | }
15 |
16 | @Override
17 | public String getTabTitle() {
18 | return title;
19 | }
20 |
21 | @Override
22 | public int getTabSelectedIcon() {
23 | return selectedIcon;
24 | }
25 |
26 | @Override
27 | public int getTabUnselectedIcon() {
28 | return unSelectedIcon;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/bean/UserAccount.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.bean;
2 |
3 | import java.io.Serializable;
4 |
5 | import io.realm.RealmObject;
6 | import io.realm.annotations.PrimaryKey;
7 | import io.realm.annotations.Required;
8 |
9 | /**
10 | * 描述: 账号密码
11 | * 作者: james
12 | * 日期: 2019/2/25 19:59
13 | * 类名: UserAccount
14 | */
15 | public class UserAccount extends RealmObject implements Serializable {
16 |
17 | @PrimaryKey
18 | private Long id;
19 |
20 | //用户名
21 | @Required
22 | private String account;
23 |
24 | //密码
25 | @Required
26 | private String psd;
27 |
28 | public Long getId() {
29 | return id;
30 | }
31 |
32 | public void setId(Long id) {
33 | this.id = id;
34 | }
35 |
36 | public String getAccount() {
37 | return account;
38 | }
39 |
40 | public void setAccount(String account) {
41 | this.account = account;
42 | }
43 |
44 | public String getPsd() {
45 | return psd;
46 | }
47 |
48 | public void setPsd(String psd) {
49 | this.psd = psd;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/utils/Conn.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.utils;
2 |
3 | public class Conn {
4 |
5 | public static int Delayed = 1500;//延迟
6 |
7 | public static String sdCardPathDown = "";//数据保存路径
8 |
9 | public static final String PagerSize = "12";// 分页加载数据的每页数据量
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/utils/CountTimerUtil.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.utils;
2 |
3 | import android.view.View;
4 | import android.view.animation.AlphaAnimation;
5 | import android.view.animation.Animation;
6 | import android.view.animation.AnimationSet;
7 | import android.view.animation.ScaleAnimation;
8 | import android.widget.TextView;
9 |
10 | /**
11 | * 描述: 倒计时
12 | * 作者: james
13 | * 日期: 2019/2/18 19:34
14 | * 类名: CountTimerUtil
15 | */
16 | public class CountTimerUtil {
17 |
18 | // 默认计时
19 | private static final int DEFAULT_REPEAT_COUNT = 4;
20 | // 最后一秒显示的文本
21 | private static final String LAST_SECOND_TEXT = "Go";
22 |
23 | // 当前的计时
24 | private static int sCurCount = DEFAULT_REPEAT_COUNT;
25 |
26 | public static void start(T animationViewTv, AnimationState animationState) {
27 | start(animationViewTv, DEFAULT_REPEAT_COUNT, animationState);
28 | }
29 |
30 | /**
31 | * @param animationViewTv 要被倒计时的控件
32 | * @param repeatCount 要倒计时多久,单位,秒。
33 | */
34 | private static void start(final T animationViewTv, final int repeatCount, AnimationState animationState) {
35 |
36 | // 设置计时
37 | sCurCount = repeatCount - 1;
38 | animationViewTv.setText(String.valueOf(sCurCount));
39 | animationViewTv.setVisibility(View.VISIBLE);
40 |
41 | // 透明度渐变动画
42 | AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
43 | // 缩放渐变动画
44 | ScaleAnimation scaleAnimation = new ScaleAnimation(
45 | 0.1f, 1.3f, 0.1f, 1.3f,
46 | Animation.RELATIVE_TO_SELF, 0.5f,
47 | Animation.RELATIVE_TO_SELF, 0.5f);
48 |
49 | scaleAnimation.setRepeatCount(sCurCount);
50 | alphaAnimation.setRepeatCount(sCurCount);
51 | alphaAnimation.setDuration(1000);
52 | scaleAnimation.setDuration(1000);
53 |
54 | // scaleAnimation.setRepeatCount(1); //设置重复次数
55 | // alphaAnimation.setRepeatMode(Animation.REVERSE); //设置重复模式为倒转,即先从小变大再变小
56 |
57 | scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
58 | @Override
59 | public void onAnimationStart(Animation animation) {
60 | animationState.start();
61 | }
62 |
63 | @Override
64 | public void onAnimationEnd(Animation animation) {
65 | // 动画结束时,隐藏
66 | animationViewTv.setVisibility(View.GONE);
67 | animationState.end();
68 | }
69 |
70 | @Override
71 | public void onAnimationRepeat(Animation animation) {
72 | // 减秒
73 | --sCurCount;
74 | // 设置文本
75 | if (sCurCount == 0) animationViewTv.setText(LAST_SECOND_TEXT);
76 | else animationViewTv.setText(String.valueOf(sCurCount));
77 |
78 | animationState.repeat();
79 | }
80 | });
81 |
82 | // 两个动画同时播放
83 | AnimationSet animationSet = new AnimationSet(true);
84 | animationSet.addAnimation(alphaAnimation);
85 | animationSet.addAnimation(scaleAnimation);
86 | animationViewTv.startAnimation(animationSet);
87 | }
88 |
89 | public interface AnimationState {
90 | void start();
91 |
92 | void repeat();
93 |
94 | void end();
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/utils/DateUtils.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.utils;
2 |
3 | import com.james.motion.R;
4 |
5 | import java.text.SimpleDateFormat;
6 | import java.util.Date;
7 |
8 | /**
9 | * 描述: 时间格式工具类
10 | * 作者: james
11 | * 日期: 2019/2/27 14:34
12 | * 类名: DateUtils
13 | */
14 | public class DateUtils {
15 |
16 | /**
17 | * 短日期补位
18 | *
19 | * @param year 年
20 | * @param month 月
21 | * @param day 日
22 | * @return 返回短时间字符串格式yyyy-MM-dd
23 | */
24 | public static String formatStringDateShort(int year, int month, int day) {
25 | return UIHelper.getString(R.string.date_year_month_day, String.valueOf(year),
26 | month < 10 ? "0" + month : String.valueOf(month),
27 | day < 10 ? "0" + day : String.valueOf(day));
28 | }
29 |
30 | /**
31 | * 获取现在时间
32 | *
33 | * @return 返回短时间字符串格式yyyy-MM-dd
34 | */
35 | public static String getStringDateShort(long time) {
36 | Date currentTime = new Date(time);
37 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
38 | String dateString = formatter.format(currentTime);
39 | return dateString;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/utils/Htmls.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.utils;
2 |
3 | /**
4 | * 用途:html 标签关键字
5 | */
6 | public interface Htmls {
7 |
8 | /**
9 | * 换行符号
10 | */
11 | String br = "
";
12 | /**
13 | * 空格
14 | */
15 | String space = " ";
16 |
17 | /**
18 | * 颜色
19 | */
20 | String color = "%s";
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/utils/MySp.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.utils;
2 |
3 | public class MySp {
4 |
5 | public static final String ISLOGIN = "isloign";//是否登录
6 |
7 | public static final String USERID = "userid";//用户ID
8 |
9 | public static final String PHONE = "phone";//手机
10 | public static final String PASSWORD = "password";//密码
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/utils/Utils.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.utils;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.james.motion.MyApplication;
6 |
7 | import java.util.regex.Matcher;
8 | import java.util.regex.Pattern;
9 |
10 | /**
11 | * 描述: 工具类
12 | * 作者: james
13 | * 日期: 2018-09-18 15:03
14 | * 类名: TabUtils
15 | */
16 |
17 | public class Utils {
18 |
19 | /**
20 | * 验证手机格式
21 | */
22 | public static boolean isMobile(String number) {
23 | /*
24 | 移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188、170
25 | 联通:130、131、132、152、155、156、185、186
26 | 电信:133、153、180、189、(1349卫通)
27 | 总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9
28 | 添加新号段:第二位新增4、6、7、9
29 | */
30 | String num = "[1][3456789]\\d{9}";//"[1]"代表第1位为数字1,"[3578]"代表第二位可以为3、5、7、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
31 | if (!isString(number)) {
32 | return false;
33 | } else {
34 | //matches():字符串是否在给定的正则表达式匹配
35 | return number.matches(num);
36 | }
37 | }
38 |
39 | /**
40 | * 手机号用****号隐藏前面中间数字
41 | */
42 | public static String settingPhone(String phone) {
43 | String phones = phone.substring(0, 3) + "****" + phone.substring(7);
44 | return phones;
45 | }
46 |
47 | /**
48 | * 验证邮箱格式
49 | */
50 | public static boolean isEmail(String email) {
51 | String emailMatch = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
52 | if (TextUtils.isEmpty(email)) {
53 | return false;
54 | } else {
55 | //matches():字符串是否在给定的正则表达式匹配
56 | return email.matches(emailMatch);
57 | }
58 | }
59 |
60 | /**
61 | * 判断是否为整数
62 | *
63 | * @param str 传入的字符串
64 | * @return 是整数返回true, 否则返回false
65 | */
66 | public static boolean isInteger(String str) {
67 | Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
68 | return pattern.matcher(str).matches();
69 | }
70 |
71 | /**
72 | * 邮箱用****号隐藏前面的字母
73 | */
74 | public static String settingEmail(String email) {
75 | String emails = email.replaceAll("(\\w?)(\\w+)(\\w)(@\\w+\\.[a-z]+(\\.[a-z]+)?)", "$1****$3$4");
76 | return emails;
77 | }
78 |
79 | /**
80 | * 验证身份证号是否符合规则
81 | *
82 | * @param IDNumber 身份证号
83 | */
84 | public static boolean personIdValidation(String IDNumber) {
85 |
86 | if (!isString(IDNumber))
87 | return false;
88 | // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母)
89 | String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
90 | "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
91 | //假设18位身份证号码:41000119910101123X 410001 19910101 123X
92 | //^开头
93 | //[1-9] 第一位1-9中的一个 4
94 | //\\d{5} 五位数字 10001(前六位省市县地区)
95 | //(18|19|20) 19(现阶段可能取值范围18xx-20xx年)
96 | //\\d{2} 91(年份)
97 | //((0[1-9])|(10|11|12)) 01(月份)
98 | //(([0-2][1-9])|10|20|30|31)01(日期)
99 | //\\d{3} 三位数字 123(第十七位奇数代表男,偶数代表女)
100 | //[0-9Xx] 0123456789Xx其中的一个 X(第十八位为校验值)
101 | //$结尾
102 |
103 | //假设15位身份证号码:410001910101123 410001 910101 123
104 | //^开头
105 | //[1-9] 第一位1-9中的一个 4
106 | //\\d{5} 五位数字 10001(前六位省市县地区)
107 | //\\d{2} 91(年份)
108 | //((0[1-9])|(10|11|12)) 01(月份)
109 | //(([0-2][1-9])|10|20|30|31)01(日期)
110 | //\\d{3} 三位数字 123(第十五位奇数代表男,偶数代表女),15位身份证不含X
111 | //$结尾
112 | return IDNumber.matches(regularExpression);
113 | }
114 |
115 | /**
116 | * 把Runnable 方法提交到主线程运行
117 | */
118 | public static void runOnUiThread(Runnable runnable) {
119 | // 在主线程运行
120 | if (android.os.Process.myTid() == android.os.Process.myTid()) {
121 | runnable.run();
122 | } else {
123 | //获取handler
124 | MyApplication.getHandler().post(runnable);
125 | }
126 | }
127 |
128 | /**
129 | * 判断s字符串是否为空
130 | */
131 | public static String isEmpry(String s) {
132 | if (null == s) {
133 | return "";
134 | } else if (s.equals("")) {
135 | return "";
136 | } else if (s.equals("null")) {
137 | return "";
138 | } else {
139 | return s;
140 | }
141 | }
142 |
143 | /**
144 | * 判断s字符串是String
145 | */
146 | public static boolean isString(String s) {
147 | if (null == s) {
148 | return false;
149 | } else if (s.equals("")) {
150 | return false;
151 | } else if (s.equals("null")) {
152 | return false;
153 | } else return s.length() > 0;
154 | }
155 |
156 | /**
157 | * 判断s字符串是String
158 | */
159 | public static boolean isString(String... s) {
160 | if (s.length <= 0)
161 | return false;
162 | for (String str : s) {
163 | if (null == str) {
164 | return false;
165 | } else if (str.equals("")) {
166 | return false;
167 | } else if (str.equals("null")) {
168 | return false;
169 | } else if (str.length() <= 0) {
170 | return false;
171 | }
172 | }
173 | return true;
174 | }
175 |
176 | /**
177 | * 从字符串中提取数字
178 | */
179 | public static String getStrNum(String str) {
180 | if (isString(str)) {
181 | String regEx = "[^0-9]";
182 | Pattern p = Pattern.compile(regEx);
183 | Matcher m = p.matcher(str);
184 | return m.replaceAll("").trim();
185 | } else {
186 | return "";
187 | }
188 | }
189 |
190 | /**
191 | * 获取Realm数据库64位秘钥
192 | *
193 | * @param key 秘钥字符
194 | * @return 秘钥
195 | */
196 | public static byte[] getRealmKey(String key) {
197 | StringBuilder newKey = new StringBuilder();
198 | for (int i = 0; i < 4; i++) {
199 | newKey.append(key);
200 | }
201 | return newKey.toString().getBytes();
202 | }
203 |
204 | }
205 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/commmon/utils/Validator.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.commmon.utils;
2 |
3 | import android.text.TextUtils;
4 |
5 | import androidx.annotation.NonNull;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import java.util.regex.Matcher;
10 | import java.util.regex.Pattern;
11 |
12 | /**
13 | * 正则表达式
14 | */
15 | public class Validator {
16 | public static boolean isNull(List objs) {
17 | if (objs == null || objs.isEmpty()) {
18 | return true;
19 | }
20 | for (Object o : objs) {
21 | if (o == null) {
22 | return true;
23 | }
24 | }
25 |
26 | return false;
27 | }
28 |
29 | public static boolean isNull(Object[] objs) {
30 | if (objs == null || objs.length == 0) return true;
31 | for (Object o : objs) {
32 | if (o == null) return true;
33 | }
34 |
35 | return false;
36 | }
37 |
38 | public static boolean password(String password) {
39 | return password.matches("[0-9a-zA-Z]{8,16}") && !password.matches("[0-9]+") && !password.matches("[a-zA-Z]+");
40 | }
41 |
42 | public static List findMac(String src) {
43 | List list = new ArrayList();
44 | if (src == null || src.equals(""))
45 | return list;
46 | Pattern pattern = Pattern
47 | .compile("[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}");
48 | Matcher matcher = pattern.matcher(src);
49 | while (matcher.find()) {
50 | list.add(matcher.group(0));
51 | }
52 | return list;
53 | }
54 |
55 | public static List findColor(String src) {
56 | List list = new ArrayList();
57 | if (src == null || src.equals(""))
58 | return list;
59 | Pattern pattern = Pattern
60 | .compile("#[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8}");
61 | Matcher matcher = pattern.matcher(src);
62 | while (matcher.find()) {
63 | list.add(matcher.group(0));
64 | }
65 | return list;
66 | }
67 |
68 | /**
69 | * 去除汉字,归正编码
70 | */
71 | public static String replaceHanzi(String input) {
72 | if (TextUtils.isEmpty(input)) {
73 | return "";
74 | }
75 |
76 | /**
77 | * 归正编码
78 | */
79 | byte[] bytes = input.getBytes();
80 | String info = "";
81 |
82 | for (int i = 0; i < bytes.length; i++) {
83 | if (bytes[i] < 0) {
84 | bytes[i] = 32;
85 | }
86 | info = info + new String(new byte[]{bytes[i]});
87 | }
88 |
89 | /**
90 | * 去除中文
91 | */
92 | Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
93 | Matcher m = p.matcher(info);
94 | List inputs = new ArrayList<>();
95 |
96 | if (m.find()) {
97 | for (int i = 0; i < info.length(); i++) {
98 | String ever = info.substring(i, i + 1);
99 | Matcher m1 = p.matcher(ever);
100 | if (m1.find()) {
101 | ever = "";
102 | }
103 | inputs.add(ever);
104 | }
105 |
106 | String inputNew = "";
107 | for (int i = 0; i < inputs.size(); i++) {
108 | inputNew = inputNew + inputs.get(i);
109 | }
110 | return inputNew.trim();
111 |
112 | }
113 | return info.trim();
114 | }
115 |
116 | /**
117 | * 验证邮箱
118 | */
119 | public static boolean checkEmail(String email) {
120 | boolean flag;
121 | try {
122 | String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
123 | Pattern regex = Pattern.compile(check);
124 | Matcher matcher = regex.matcher(email);
125 | flag = matcher.matches();
126 | } catch (Exception e) {
127 | flag = false;
128 | }
129 | return flag;
130 | }
131 |
132 | /**
133 | * 获得汉语拼音首字母
134 | */
135 | public static String getAlpha(String str) {
136 | if (str == null) {
137 | return "#";
138 | }
139 |
140 | if (str.trim().length() == 0) {
141 | return "#";
142 | }
143 |
144 | char c = str.trim().substring(0, 1).charAt(0);
145 | // 正则表达式,判断首字母是否是英文字母
146 | Pattern pattern = Pattern.compile("^[A-Za-z]+$");
147 | if (pattern.matcher(c + "").matches()) {
148 | return (c + "").toUpperCase();
149 | } else {
150 | return "#";
151 | }
152 | }
153 |
154 | /**
155 | * 校验URL
156 | */
157 | public static boolean checkUrl(String url) {
158 | if (TextUtils.isEmpty(url)) {
159 | return false;
160 | }
161 | String temp = url.replace(" ", "");
162 | if (!temp.startsWith("http") && !temp.startsWith("https")) {
163 | temp = "https://" + temp;
164 | }
165 | boolean flag;
166 | try {
167 | String check = "(http|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?";
168 | Pattern regex = Pattern.compile(check, Pattern.CASE_INSENSITIVE);
169 | Matcher matcher = regex.matcher(temp.replaceAll(" ", ""));
170 | flag = matcher.matches();
171 | } catch (Exception e) {
172 | flag = false;
173 | }
174 |
175 | return flag;
176 | }
177 |
178 |
179 | public static boolean checkColor(@NonNull String color) {
180 |
181 | return color.matches("^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$");
182 | }
183 |
184 | /**
185 | * @return 从下载连接中解析出文件名
186 | */
187 | @NonNull
188 | public static String getNameFromUrl(String url) {
189 | String temp = url;
190 | if (url.contains("?")) {
191 | temp = url.substring(0, url.indexOf("?"));
192 | }
193 | temp = temp.substring(temp.lastIndexOf("/") + 1);
194 | if (TextUtils.isEmpty(temp)) {
195 | temp = System.currentTimeMillis() + ".temp";
196 | }
197 | return temp;
198 | }
199 |
200 |
201 | }
202 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/db/DBHelper.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.db;
2 |
3 | import com.james.motion.commmon.bean.SportMotionRecord;
4 | import com.james.motion.commmon.bean.UserAccount;
5 |
6 | import java.util.List;
7 |
8 | public interface DBHelper {
9 |
10 | /**
11 | * 增加 运动数据
12 | *
13 | * @param record 运动数据
14 | */
15 | void insertSportRecord(SportMotionRecord record);
16 |
17 | /**
18 | * 删除 运动数据
19 | *
20 | * @param record 运动数据
21 | */
22 | void deleteSportRecord(SportMotionRecord record);
23 |
24 | /**
25 | * 删除 全部运动数据
26 | */
27 | void deleteSportRecord();
28 |
29 | /**
30 | * 获取 某人的运动数据
31 | *
32 | * @param master 登陆者
33 | */
34 | List queryRecordList(int master);
35 |
36 | /**
37 | * 获取 某人的运动数据
38 | *
39 | * @param master 登陆者
40 | * @param dateTag 时间标记
41 | */
42 | List queryRecordList(int master, String dateTag);
43 |
44 | /**
45 | * 获取 全部的运动数据
46 | */
47 | List queryRecordList();
48 |
49 | /**
50 | * 获取 运动数据
51 | *
52 | * @param master 登陆者
53 | * @param startTime 开始时间
54 | * @param endTime 结束时间
55 | */
56 | SportMotionRecord queryRecord(int master, long startTime, long endTime);
57 |
58 | /**
59 | * 获取 运动数据
60 | *
61 | * @param master 登陆者
62 | * @param dateTag 时间标记
63 | */
64 | SportMotionRecord queryRecord(int master, String dateTag);
65 |
66 | /**
67 | * 关闭数据库
68 | */
69 | void closeRealm();
70 |
71 | /**
72 | * 增加 账号
73 | *
74 | * @param account 账号
75 | */
76 | void insertAccount(UserAccount account);
77 |
78 | /**
79 | * 获取 账号
80 | *
81 | * @param account 账号
82 | */
83 | UserAccount queryAccount(String account);
84 |
85 | /**
86 | * 查詢 账号
87 | *
88 | * @param account 账号
89 | * @param psd 密码
90 | */
91 | boolean checkAccount(String account, String psd);
92 |
93 | /**
94 | * 查詢 账号
95 | *
96 | * @param account 账号
97 | */
98 | boolean checkAccount(String account);
99 |
100 | /**
101 | * 获取 全部的账号
102 | */
103 | List queryAccountList();
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/db/DataManager.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.db;
2 |
3 | import com.james.motion.commmon.bean.SportMotionRecord;
4 | import com.james.motion.commmon.bean.UserAccount;
5 |
6 | import java.util.List;
7 |
8 | public class DataManager implements DBHelper {
9 |
10 | private RealmHelper realmHelper;
11 |
12 | private DataManager() {
13 |
14 | }
15 |
16 | public DataManager(RealmHelper helper) {
17 | realmHelper = helper;
18 | }
19 |
20 | @Override
21 | public void insertSportRecord(SportMotionRecord record) {
22 | realmHelper.insertSportRecord(record);
23 | }
24 |
25 | @Override
26 | public void deleteSportRecord(SportMotionRecord record) {
27 | realmHelper.deleteSportRecord(record);
28 | }
29 |
30 | @Override
31 | public void deleteSportRecord() {
32 | realmHelper.deleteSportRecord();
33 | }
34 |
35 | @Override
36 | public List queryRecordList(int master) {
37 | return realmHelper.queryRecordList(master);
38 | }
39 |
40 | @Override
41 | public List queryRecordList(int master, String dateTag) {
42 | return realmHelper.queryRecordList(master, dateTag);
43 | }
44 |
45 | @Override
46 | public List queryRecordList() {
47 | return realmHelper.queryRecordList();
48 | }
49 |
50 | @Override
51 | public SportMotionRecord queryRecord(int master, long startTime, long endTime) {
52 | return realmHelper.queryRecord(master, startTime, endTime);
53 | }
54 |
55 | @Override
56 | public SportMotionRecord queryRecord(int master, String dateTag) {
57 | return realmHelper.queryRecord(master, dateTag);
58 | }
59 |
60 | @Override
61 | public void closeRealm() {
62 | realmHelper.closeRealm();
63 | }
64 |
65 | @Override
66 | public void insertAccount(UserAccount account) {
67 | realmHelper.insertAccount(account);
68 | }
69 |
70 | @Override
71 | public UserAccount queryAccount(String account) {
72 | return realmHelper.queryAccount(account);
73 | }
74 |
75 | @Override
76 | public boolean checkAccount(String account, String psd) {
77 | return realmHelper.checkAccount(account, psd);
78 | }
79 |
80 | @Override
81 | public boolean checkAccount(String account) {
82 | return realmHelper.checkAccount(account);
83 | }
84 |
85 | @Override
86 | public List queryAccountList() {
87 | return realmHelper.queryAccountList();
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/sport_motion/LocationService.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.sport_motion;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.Binder;
6 | import android.os.IBinder;
7 |
8 | import androidx.annotation.Nullable;
9 |
10 | import com.amap.api.location.AMapLocation;
11 | import com.amap.api.location.AMapLocationClient;
12 | import com.amap.api.location.AMapLocationClientOption;
13 | import com.amap.api.location.AMapLocationListener;
14 | import com.amap.api.maps.model.LatLng;
15 | import com.james.motion.commmon.utils.LogUtils;
16 | import com.james.motion.sport_motion.servicecode.RecordService;
17 | import com.james.motion.sport_motion.servicecode.impl.RecordServiceImpl;
18 |
19 | /**
20 | * 定位的Service类,用户在运动时此服务会在后台进行定位。
21 | */
22 | public class LocationService extends Service {
23 |
24 | private InterfaceLocationed interfaceLocationed = null;
25 |
26 | public static final String TAG = "LocationService";
27 |
28 | public final IBinder mBinder = new LocalBinder();
29 |
30 | public class LocalBinder extends Binder {
31 | // 在Binder中定义一个自定义的接口用于数据交互
32 | // 这里直接把当前的服务传回给宿主
33 | public LocationService getService() {
34 | return LocationService.this;
35 | }
36 | }
37 |
38 | //定位的时间间隔,单位是毫秒
39 | private static final int LOCATION_SPAN = 10 * 1000;
40 |
41 | //百度地图中定位的类
42 | public AMapLocationClient mLocationClient = null;
43 | //记录着运动中移动的坐标位置
44 | // private List mSportLatLngs = new LinkedList<>();
45 |
46 | //记录运动信息的Service
47 | private RecordService mRecordService = null;
48 |
49 | @Override
50 | public void onCreate() {
51 | super.onCreate();
52 |
53 | //声明LocationClient类
54 | mLocationClient = new AMapLocationClient(this);
55 | //给定位类加入自定义的配置
56 | initLocationOption();
57 | //注册监听函数
58 | mLocationClient.setLocationListener(MyAMapLocationListener);
59 |
60 | //初始化信息记录类
61 | mRecordService = new RecordServiceImpl(this);
62 |
63 | //启动定位
64 | mLocationClient.startLocation();
65 | }
66 |
67 | //初始化定位的配置
68 | private void initLocationOption() {
69 | AMapLocationClientOption mOption = new AMapLocationClientOption();
70 | mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
71 | mOption.setGpsFirst(true);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
72 | mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
73 | mOption.setInterval(4000);//可选,设置定位间隔。默认为2秒
74 | mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true
75 | mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false
76 | mOption.setOnceLocationLatest(false);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
77 | AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
78 | mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false
79 | mOption.setWifiScan(true); //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
80 | mOption.setLocationCacheEnable(false); //可选,设置是否使用缓存定位,默认为true
81 | mOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT);//可选,设置逆地理信息的语言,默认值为默认语言(根据所在地区选择语言)
82 | mLocationClient.setLocationOption(mOption);
83 | }
84 |
85 | //定位回调
86 | private AMapLocationListener MyAMapLocationListener = aMapLocation -> {
87 |
88 | if (null == aMapLocation)
89 | return;
90 |
91 | if (aMapLocation.getErrorCode() == 0) {
92 | //先暂时获得经纬度信息,并将其记录在List中
93 | LogUtils.d("纬度信息为" + aMapLocation.getLatitude() + "\n经度信息为" + aMapLocation.getLongitude());
94 | LatLng locationValue = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
95 | // mSportLatLngs.add(locationValue);
96 |
97 | //将运动信息上传至服务器
98 | recordLocation(locationValue, aMapLocation.getLocationDetail());
99 |
100 | //定位成功,发送通知
101 | if (null != interfaceLocationed)
102 | interfaceLocationed.locationed(aMapLocation);
103 |
104 | } else {
105 | String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
106 | LogUtils.e("AmapErr", errText);
107 | }
108 | };
109 |
110 | private void recordLocation(LatLng latLng, String location) {
111 | if (mRecordService != null) {
112 | mRecordService.recordSport(latLng, location);
113 | }
114 | }
115 |
116 | @Nullable
117 | @Override
118 | public IBinder onBind(Intent intent) {
119 | LogUtils.i(TAG, "绑定服务 The service is binding!");
120 | // 绑定服务,把当前服务的IBinder对象的引用传递给宿主
121 | return mBinder;
122 | }
123 |
124 | @Override
125 | public boolean onUnbind(Intent intent) {
126 | LogUtils.i(TAG, "解除绑定服务 The service is unbinding!");
127 | //解除绑定后销毁服务
128 | stopSelf();
129 | return super.onUnbind(intent);
130 | }
131 |
132 | @Override
133 | public void onDestroy() {
134 | super.onDestroy();
135 | if (null != mLocationClient) {
136 | mLocationClient.stopLocation();
137 | mLocationClient.unRegisterLocationListener(MyAMapLocationListener);
138 | mLocationClient.onDestroy();
139 | mLocationClient = null;
140 | }
141 | }
142 |
143 | public void setInterfaceLocationed(InterfaceLocationed interfaceLocationed) {
144 | this.interfaceLocationed = null;
145 | this.interfaceLocationed = interfaceLocationed;
146 | }
147 |
148 | public interface InterfaceLocationed {
149 | void locationed(AMapLocation aMapLocation);
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/sport_motion/TraceRePlay.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.sport_motion;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 | import android.os.Message;
6 |
7 | import com.amap.api.maps.model.LatLng;
8 |
9 | import java.lang.ref.WeakReference;
10 | import java.util.List;
11 |
12 | /**
13 | * 轨迹回放工具类
14 | */
15 | public class TraceRePlay implements Runnable {
16 | private TraceRePlayHandler mTraceHandler;
17 | private static final int TRACE_MOVE = 1;
18 | private static final int TRACE_FINISH = 2;
19 | private List mTraceList;
20 | private int mIntervalMillisecond;
21 | private TraceRePlayListener mTraceUpdateListener;
22 | private boolean mStop = false;
23 |
24 | /**
25 | * 构造轨迹回放需要,List、时间间隔、回调listenenr
26 | *
27 | * @param list 轨迹list
28 | * @param intervalMillisecond 回调时间间隔
29 | * @param listener 回调listener
30 | */
31 | public TraceRePlay(List list, int intervalMillisecond,
32 | TraceRePlayListener listener) {
33 | mTraceList = list;
34 | mIntervalMillisecond = intervalMillisecond;
35 | mTraceUpdateListener = listener;
36 | mTraceHandler = new TraceRePlayHandler(this);
37 | }
38 |
39 | public void stopTrace() {
40 | mStop = true;
41 | }
42 |
43 | /**
44 | * 接收run发送的消息,达到按照设定时间间隔轮巡轨迹list目的
45 | */
46 | static class TraceRePlayHandler extends Handler {
47 | WeakReference mTraceRePaly;
48 |
49 | public TraceRePlayHandler(TraceRePlay traceRePlay) {
50 | super(Looper.getMainLooper());
51 | mTraceRePaly = new WeakReference<>(traceRePlay);
52 | }
53 |
54 | @Override
55 | public void handleMessage(Message message) {
56 | super.handleMessage(message);
57 | TraceRePlay trace = mTraceRePaly.get();
58 | switch (message.what) {
59 | case TRACE_MOVE:
60 | LatLng latLng = (LatLng) message.obj;
61 | if (trace.mTraceUpdateListener != null) {
62 | trace.mTraceUpdateListener.onTraceUpdating(latLng);
63 | }
64 | break;
65 | case TRACE_FINISH:
66 | if (trace.mTraceUpdateListener != null) {
67 | trace.mTraceUpdateListener.onTraceUpdateFinish();
68 | }
69 | break;
70 | default:
71 | break;
72 | }
73 | }
74 | }
75 |
76 | public interface TraceRePlayListener {
77 | /**
78 | * 轨迹回放过程回调
79 | *
80 | * @param latLng
81 | */
82 | public void onTraceUpdating(LatLng latLng);
83 |
84 | /**
85 | * 轨迹回放结束回调
86 | */
87 | public void onTraceUpdateFinish();
88 |
89 | }
90 |
91 | /**
92 | * 将mTraceList 按照给定的时间间隔和次序发消息给TraceRePlayHandler以达到轨迹回放效果
93 | */
94 | @Override
95 | public void run() {
96 | if (mTraceList != null) {
97 | for (int i = 0; i < mTraceList.size(); i++) {
98 | if (mStop) {
99 | break;
100 | }
101 | LatLng latLng = mTraceList.get(i);
102 | Message message = mTraceHandler.obtainMessage();
103 | message.what = TRACE_MOVE;
104 | message.obj = latLng;
105 | mTraceHandler.sendMessage(message);
106 | try {
107 | Thread.sleep(mIntervalMillisecond);
108 | } catch (InterruptedException e) {
109 | e.printStackTrace();
110 | }
111 | }
112 | if (!mStop) {
113 | Message finishMessage = mTraceHandler.obtainMessage();
114 | finishMessage.what = TRACE_FINISH;
115 | mTraceHandler.sendMessage(finishMessage);
116 | }
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/sport_motion/servicecode/RecordService.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.sport_motion.servicecode;
2 |
3 | import com.amap.api.maps.model.LatLng;
4 |
5 | /**
6 | * 上传跑步信息的Service接口
7 | */
8 | public interface RecordService {
9 |
10 | //记录运动坐标和大概描述信息
11 | void recordSport(LatLng latLng, String location);
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/sport_motion/servicecode/impl/RecordServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.sport_motion.servicecode.impl;
2 |
3 | import android.content.Context;
4 |
5 | import com.amap.api.maps.model.LatLng;
6 | import com.james.motion.commmon.utils.LogUtils;
7 | import com.james.motion.sport_motion.servicecode.RecordService;
8 |
9 | /**
10 | * 记录运动信息的实现类
11 | */
12 | public class RecordServiceImpl implements RecordService {
13 |
14 | private Context mContext;
15 |
16 | public RecordServiceImpl(Context context) {
17 | this.mContext = context;
18 | }
19 |
20 | @Override
21 | public void recordSport(LatLng latLng, String location) {
22 | LogUtils.d("保存定位数据 = " + latLng.latitude + ":" + latLng.longitude + " " + location);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.os.Message;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.Toast;
12 |
13 | import androidx.annotation.Nullable;
14 | import androidx.fragment.app.Fragment;
15 |
16 | import com.james.motion.commmon.utils.Utils;
17 | import com.james.motion.ui.weight.CustomProgressDialog;
18 |
19 | import butterknife.ButterKnife;
20 | import butterknife.Unbinder;
21 |
22 | /**
23 | * 描述: Fragment基类
24 | * 作者: james
25 | * 日期: 2019/2/25 15:42
26 | * 类名: BaseFragment
27 | */
28 | public abstract class BaseFragment extends Fragment {
29 |
30 | protected String TAG = BaseFragment.class.getSimpleName();
31 |
32 | private Unbinder bind;
33 |
34 | protected Context context;
35 |
36 | private Toast mToast = null;
37 |
38 | private static final int DISMISS = 1001;
39 | private static final int SHOW = 1002;
40 | private CustomProgressDialog progressDialog = null;
41 |
42 | @SuppressLint("HandlerLeak")
43 | private Handler mHandler = new Handler() {
44 |
45 | @Override
46 | public void handleMessage(Message msg) {
47 | switch (msg.what) {
48 | case SHOW:
49 | if (progressDialog != null) {
50 | progressDialog.setTouchAble((Boolean) msg.obj);
51 | progressDialog.show();
52 | }
53 | break;
54 | case DISMISS:
55 | if (progressDialog != null && progressDialog.isShowing()) {
56 | progressDialog.dismiss();
57 | }
58 | break;
59 | default:
60 | break;
61 | }
62 | }
63 | };
64 |
65 |
66 | @Nullable
67 | @Override
68 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
69 |
70 | View inflate = inflater.inflate(getLayoutId(), container, false);
71 |
72 | bind = ButterKnife.bind(this, inflate);
73 |
74 | context = getActivity();
75 |
76 | initData(savedInstanceState);
77 |
78 | initListener();
79 |
80 | mToast = Toast.makeText(context, "", Toast.LENGTH_SHORT);
81 | if (progressDialog == null) {
82 | progressDialog = new CustomProgressDialog(context);
83 | }
84 | return inflate;
85 | }
86 |
87 | public abstract int getLayoutId();
88 |
89 | public abstract void initData(Bundle savedInstanceState);
90 |
91 | public abstract void initListener();
92 |
93 | @Override
94 | public void onResume() {
95 | super.onResume();
96 |
97 | if (mToast == null)
98 | mToast = Toast.makeText(context, "", Toast.LENGTH_SHORT);
99 | if (progressDialog == null) {
100 | progressDialog = new CustomProgressDialog(context);
101 | }
102 | }
103 |
104 | /**
105 | * 显示加载视图
106 | *
107 | * @param isTouchAble true:可点击 false:不可点击 默认是可点击
108 | */
109 | protected void showLoadingView(boolean isTouchAble) {
110 | if (null != mHandler && !isShowingLoadingView()) {
111 | Message m = mHandler.obtainMessage(SHOW, isTouchAble);
112 | mHandler.sendMessage(m);
113 | }
114 | }
115 |
116 | protected void showLoadingView() {
117 | if (!isShowingLoadingView())
118 | showLoadingView(true);
119 | }
120 |
121 | /**
122 | * 关闭加载视图
123 | */
124 | protected void dismissLoadingView() {
125 | if (null != mHandler)
126 | mHandler.sendEmptyMessage(DISMISS);
127 | }
128 |
129 | protected boolean isShowingLoadingView() {
130 | if (progressDialog != null) {
131 | return progressDialog.isShowing();
132 | } else {
133 | return false;
134 | }
135 | }
136 |
137 |
138 | public void showToast(String s) {
139 | if (!Utils.isString(s))
140 | return;
141 | if (mToast != null) {
142 | mToast.cancel();
143 | mToast = null;
144 | }
145 | if (null != context) {
146 | mToast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
147 | mToast.show();
148 | }
149 | }
150 |
151 | @Override
152 | public void onPause() {
153 |
154 | if (mToast != null) {
155 | mToast.cancel();
156 | mToast = null;
157 | }
158 | if (progressDialog != null && progressDialog.isShowing()) {
159 | progressDialog.dismiss();
160 | }
161 | progressDialog = null;
162 |
163 | super.onPause();
164 | }
165 |
166 | @Override
167 | public void onDestroy() {
168 | if (bind != null) {
169 | bind.unbind();
170 | }
171 | if (progressDialog != null && progressDialog.isShowing()) {
172 | progressDialog.dismiss();
173 | }
174 | progressDialog = null;
175 | if (null != mHandler) {
176 | mHandler.removeMessages(DISMISS);
177 | mHandler.removeMessages(SHOW);
178 | mHandler.removeCallbacksAndMessages(null);
179 | mHandler = null;
180 | }
181 | super.onDestroy();
182 | }
183 |
184 | }
185 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/activity/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.activity;
2 |
3 | import android.Manifest;
4 | import android.content.Intent;
5 | import android.os.Build;
6 | import android.os.Bundle;
7 | import android.view.KeyEvent;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import com.blankj.utilcode.util.SPUtils;
12 | import com.blankj.utilcode.util.ToastUtils;
13 | import com.gyf.immersionbar.ImmersionBar;
14 | import com.james.motion.MyApplication;
15 | import com.james.motion.R;
16 | import com.james.motion.commmon.utils.MySp;
17 | import com.james.motion.commmon.utils.UIHelper;
18 | import com.james.motion.ui.BaseActivity;
19 | import com.james.motion.ui.permission.PermissionHelper;
20 | import com.james.motion.ui.permission.PermissionListener;
21 | import com.james.motion.ui.weight.CountDownProgressView;
22 |
23 | import butterknife.BindView;
24 |
25 | /**
26 | * 描述: 闪屏界面
27 | * 作者: james
28 | * 日期: 2019/2/25 16:20
29 | * 类名: SplashActivity
30 | */
31 | public class SplashActivity extends BaseActivity {
32 |
33 | @BindView(R.id.im_url)
34 | ImageView imUrl;
35 | @BindView(R.id.countdownProgressView)
36 | CountDownProgressView countDownProgressView;
37 | @BindView(R.id.versions)
38 | TextView versions;
39 |
40 | /**
41 | * 上次点击返回键的时间
42 | */
43 | private long lastBackPressed;
44 | /**
45 | * 上次点击返回键的时间
46 | */
47 | private static final int QUIT_INTERVAL = 3000;
48 |
49 | // 要申请的权限
50 | private static String[] PERMISSIONS_STORAGE = {
51 | Manifest.permission.WRITE_EXTERNAL_STORAGE,
52 | Manifest.permission.READ_EXTERNAL_STORAGE,
53 | Manifest.permission.ACCESS_FINE_LOCATION,
54 | Manifest.permission.ACCESS_COARSE_LOCATION};
55 |
56 | @Override
57 | protected void initImmersionBar() {
58 | super.initImmersionBar();
59 | if (ImmersionBar.hasNavigationBar(this)) {
60 | ImmersionBar.with(this).transparentNavigationBar().init();
61 | }
62 | }
63 |
64 | @Override
65 | public int getLayoutId() {
66 | return R.layout.activity_splash;
67 | }
68 |
69 | @Override
70 | public void initData(Bundle savedInstanceState) {
71 |
72 | imUrl.setImageResource(R.mipmap.splash_bg);
73 |
74 | versions.setText(UIHelper.getString(R.string.splash_appversionname, MyApplication.getAppVersionName()));
75 |
76 | countDownProgressView.setTimeMillis(2000);
77 | countDownProgressView.setProgressType(CountDownProgressView.ProgressType.COUNT_BACK);
78 | countDownProgressView.start();
79 | }
80 |
81 | @Override
82 | public void initListener() {
83 | countDownProgressView.setOnClickListener(v -> {
84 |
85 | countDownProgressView.stop();
86 |
87 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
88 | // 获取权限
89 | PermissionHelper.requestPermissions(this, PERMISSIONS_STORAGE, new PermissionListener() {
90 | @Override
91 | public void onPassed() {
92 | startActivity();
93 | }
94 | });
95 | } else {
96 | startActivity();
97 | }
98 | });
99 |
100 | countDownProgressView.setProgressListener(progress -> {
101 | if (progress == 0) {
102 | // 版本判断。当手机系统大于 23 时,才有必要去判断权限是否获取
103 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
104 | // 获取权限
105 | PermissionHelper.requestPermissions(this, PERMISSIONS_STORAGE,
106 | getResources().getString(R.string.app_name) + "需要获取存储、位置权限", new PermissionListener() {
107 | @Override
108 | public void onPassed() {
109 | startActivity();
110 | }
111 | });
112 | } else {
113 | startActivity();
114 | }
115 | }
116 | });
117 | }
118 |
119 | public void startActivity() {
120 | if (SPUtils.getInstance().getBoolean(MySp.ISLOGIN)) {
121 | startActivity(new Intent(SplashActivity.this, HomeActivity.class));
122 | finish();
123 | } else {
124 | startActivity(new Intent(SplashActivity.this, LoginActivity.class));
125 | finish();
126 | }
127 | countDownProgressView.stop();
128 | }
129 |
130 | @Override
131 | public boolean onKeyDown(int keyCode, KeyEvent event) {
132 | if (event.getAction() == KeyEvent.ACTION_DOWN) {
133 | if (keyCode == KeyEvent.KEYCODE_BACK) { // 表示按返回键 时的操作
134 | long backPressed = System.currentTimeMillis();
135 | if (backPressed - lastBackPressed > QUIT_INTERVAL) {
136 | lastBackPressed = backPressed;
137 | ToastUtils.showShort("再按一次退出");
138 | } else {
139 | if (countDownProgressView != null) {
140 | countDownProgressView.stop();
141 | countDownProgressView.clearAnimation();
142 | }
143 | moveTaskToBack(false);
144 | MyApplication.closeApp(this);
145 | finish();
146 | }
147 | }
148 | }
149 | return false;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/activity/SportRecordDetailsActivity.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.activity;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.widget.TextView;
7 |
8 | import androidx.fragment.app.Fragment;
9 | import androidx.fragment.app.FragmentManager;
10 | import androidx.fragment.app.FragmentPagerAdapter;
11 | import androidx.viewpager.widget.ViewPager;
12 |
13 | import com.blankj.utilcode.util.ToastUtils;
14 | import com.flyco.tablayout.CommonTabLayout;
15 | import com.flyco.tablayout.listener.CustomTabEntity;
16 | import com.flyco.tablayout.listener.OnTabSelectListener;
17 | import com.james.motion.R;
18 | import com.james.motion.commmon.bean.PathRecord;
19 | import com.james.motion.commmon.bean.TabEntity;
20 | import com.james.motion.ui.BaseActivity;
21 | import com.james.motion.ui.fragment.SportRecordDetailsFragment;
22 | import com.james.motion.ui.fragment.SportRecordDetailsMapFragment;
23 | import com.james.motion.ui.fragment.SportRecordDetailsSpeedFragment;
24 | import com.james.motion.ui.weight.AMapScrollViewPager;
25 |
26 | import java.util.ArrayList;
27 |
28 | import butterknife.BindView;
29 |
30 | /**
31 | * 描述: 运动记录详情
32 | * 作者: james
33 | * 日期: 2019/2/27 15:10
34 | * 类名: SportRecordDetailsActivity
35 | */
36 | public class SportRecordDetailsActivity extends BaseActivity {
37 |
38 | @BindView(R.id.tv_title)
39 | TextView tvTitle;
40 | @BindView(R.id.commonTabLayout)
41 | CommonTabLayout commonTabLayout;
42 | @BindView(R.id.vp)
43 | AMapScrollViewPager mViewPager;
44 |
45 | private ArrayList mTabEntities = new ArrayList<>();
46 | private String[] mTitles = {"轨迹", "详情", "配速"};
47 | private ArrayList mFragments = new ArrayList() {{
48 | add(new SportRecordDetailsMapFragment());
49 | add(new SportRecordDetailsFragment());
50 | add(new SportRecordDetailsSpeedFragment());
51 | }};
52 |
53 | private PathRecord pathRecord = null;
54 |
55 | public static String SPORT_DATA = "SPORT_DATA";
56 |
57 | public static void StartActivity(Activity activity, PathRecord pathRecord) {
58 | Intent intent = new Intent();
59 | Bundle bundle = new Bundle();
60 | bundle.putParcelable(SPORT_DATA, pathRecord);
61 | intent.putExtras(bundle);
62 | intent.setClass(activity, SportRecordDetailsActivity.class);
63 | activity.startActivity(intent);
64 | }
65 |
66 | @Override
67 | public int getLayoutId() {
68 | return R.layout.activity_sportrecorddetails;
69 | }
70 |
71 | @Override
72 | public void initData(Bundle savedInstanceState) {
73 | tvTitle.setText("运动记录");
74 |
75 | if (getIntent().hasExtra(SPORT_DATA)) {
76 | pathRecord = getIntent().getParcelableExtra(SPORT_DATA);
77 | } else {
78 | ToastUtils.showShort("参数错误!");
79 | finish();
80 | }
81 |
82 | Bundle bundle = new Bundle();
83 | bundle.putParcelable(SPORT_DATA, pathRecord);
84 | for (int i = 0, size = mTitles.length; i < size; i++) {
85 | mTabEntities.add(new TabEntity(mTitles[i], 0, 0));
86 | mFragments.get(i).setArguments(bundle);
87 | }
88 |
89 | commonTabLayout.setTabData(mTabEntities);
90 |
91 | //设置缓存页面数量,默认为2,防止地图显示重载丢失已设置的数据
92 | mViewPager.setOffscreenPageLimit(4);
93 |
94 | mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
95 |
96 | mViewPager.setCurrentItem(0);
97 | }
98 |
99 | @Override
100 | public void initListener() {
101 | commonTabLayout.setOnTabSelectListener(new OnTabSelectListener() {
102 | @Override
103 | public void onTabSelect(int position) {
104 | mViewPager.setCurrentItem(position);
105 | }
106 |
107 | @Override
108 | public void onTabReselect(int position) {
109 |
110 | }
111 | });
112 | mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
113 | @Override
114 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
115 |
116 | }
117 |
118 | @Override
119 | public void onPageSelected(int position) {
120 | commonTabLayout.setCurrentTab(position);
121 | }
122 |
123 | @Override
124 | public void onPageScrollStateChanged(int state) {
125 |
126 | }
127 | });
128 | }
129 |
130 | private class MyPagerAdapter extends FragmentPagerAdapter {
131 |
132 | MyPagerAdapter(FragmentManager fm) {
133 | super(fm);
134 | }
135 |
136 | @Override
137 | public int getCount() {
138 | return mFragments.size();
139 | }
140 |
141 | @Override
142 | public CharSequence getPageTitle(int position) {
143 | return mTitles[position];
144 | }
145 |
146 | @Override
147 | public Fragment getItem(int position) {
148 | return mFragments.get(position);
149 | }
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/activity/SportsActivity.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.activity;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.widget.Button;
6 | import android.widget.TextView;
7 |
8 | import com.blankj.utilcode.util.SPUtils;
9 | import com.james.motion.R;
10 | import com.james.motion.commmon.bean.SportMotionRecord;
11 | import com.james.motion.commmon.utils.LogUtils;
12 | import com.james.motion.commmon.utils.MySp;
13 | import com.james.motion.db.DataManager;
14 | import com.james.motion.db.RealmHelper;
15 | import com.james.motion.ui.BaseActivity;
16 | import com.james.motion.ui.permission.PermissionHelper;
17 | import com.james.motion.ui.permission.PermissionListener;
18 | import com.james.motion.ui.permission.Permissions;
19 |
20 | import java.text.DecimalFormat;
21 | import java.util.List;
22 |
23 | import butterknife.BindView;
24 | import butterknife.OnClick;
25 |
26 | /**
27 | * 描述: 运动轨迹
28 | * 作者: james
29 | * 日期: 2019/2/27 14:50
30 | * 类名: SportsActivity
31 | */
32 | public class SportsActivity extends BaseActivity {
33 |
34 | @BindView(R.id.tv_sport_mile)
35 | TextView tvSportMile;
36 | @BindView(R.id.tv_sport_count)
37 | TextView tvSportCount;
38 | @BindView(R.id.tv_sport_time)
39 | TextView tvSportTime;
40 | @BindView(R.id.btStart)
41 | Button btStart;
42 |
43 | private DecimalFormat decimalFormat = new DecimalFormat("0.00");
44 |
45 | private final int SPORT = 0x0012;
46 |
47 | private DataManager dataManager = null;
48 |
49 | @Override
50 | public int getLayoutId() {
51 | return R.layout.activity_sports;
52 | }
53 |
54 | @Override
55 | public void initData(Bundle savedInstanceState) {
56 | dataManager = new DataManager(new RealmHelper());
57 |
58 | upDateUI();
59 | }
60 |
61 | @Override
62 | public void initListener() {
63 |
64 | }
65 |
66 | @OnClick(R.id.btStart)
67 | public void onViewClicked() {
68 | PermissionHelper.requestPermissions(this, Permissions.PERMISSIONS_LOCATION,
69 | getResources().getString(R.string.app_name) + "需要获取位置", new PermissionListener() {
70 | @Override
71 | public void onPassed() {
72 | startActivityForResult(new Intent(SportsActivity.this, SportMapActivity.class), SPORT);
73 | }
74 | });
75 | }
76 |
77 | private void upDateUI() {
78 | try {
79 | List records = dataManager.queryRecordList(Integer.parseInt(SPUtils.getInstance().getString(MySp.USERID, "0")));
80 | if (null != records) {
81 |
82 | double sportMile = 0;
83 | long sportTime = 0;
84 | for (SportMotionRecord record : records) {
85 | sportMile += record.getDistance();
86 | sportTime += record.getDuration();
87 | }
88 | tvSportMile.setText(decimalFormat.format(sportMile / 1000d));
89 | tvSportCount.setText(String.valueOf(records.size()));
90 | tvSportTime.setText(decimalFormat.format((double) sportTime / 60d));
91 | }
92 | } catch (Exception e) {
93 | LogUtils.e("获取运动数据失败", e);
94 | }
95 | }
96 |
97 | @Override
98 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
99 | super.onActivityResult(requestCode, resultCode, data);
100 | if (resultCode != RESULT_OK)
101 | return;
102 | switch (requestCode) {
103 | case SPORT:
104 | upDateUI();
105 | setResult(RESULT_OK);
106 | break;
107 | default:
108 | break;
109 | }
110 | }
111 |
112 | @Override
113 | protected void onDestroy() {
114 | if (null != dataManager)
115 | dataManager.closeRealm();
116 | super.onDestroy();
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/adapter/SportCalendarAdapter.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.adapter;
2 |
3 | import androidx.annotation.Nullable;
4 |
5 | import com.chad.library.adapter.base.BaseQuickAdapter;
6 | import com.chad.library.adapter.base.BaseViewHolder;
7 | import com.james.motion.R;
8 | import com.james.motion.commmon.bean.PathRecord;
9 | import com.james.motion.sport_motion.MotionUtils;
10 |
11 | import java.text.DecimalFormat;
12 | import java.util.List;
13 |
14 | /**
15 | * 描述: 运动日历
16 | * 作者: james
17 | * 日期: 2019/2/27 14:02
18 | * 类名: SportCalendarAdapter
19 | */
20 | public class SportCalendarAdapter extends BaseQuickAdapter {
21 |
22 | private DecimalFormat decimalFormat = new DecimalFormat("0.00");
23 | private DecimalFormat intFormat = new DecimalFormat("#");
24 |
25 | public SportCalendarAdapter(int layoutResId, @Nullable List data) {
26 | super(layoutResId, data);
27 | }
28 |
29 | @Override
30 | protected void convert(BaseViewHolder helper, PathRecord item) {
31 | helper.setText(R.id.distance, decimalFormat.format(item.getDistance() / 1000d));
32 | helper.setText(R.id.duration, MotionUtils.formatseconds(item.getDuration()));
33 | helper.setText(R.id.calorie, intFormat.format(item.getCalorie()));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/fragment/FastLoginFragment.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.fragment;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.SystemClock;
7 | import android.text.Editable;
8 | import android.text.TextUtils;
9 | import android.text.TextWatcher;
10 | import android.view.View;
11 | import android.view.WindowManager;
12 | import android.view.inputmethod.InputMethodManager;
13 | import android.widget.Chronometer;
14 | import android.widget.EditText;
15 | import android.widget.ImageButton;
16 |
17 | import com.blankj.utilcode.util.SPUtils;
18 | import com.blankj.utilcode.util.ToastUtils;
19 | import com.james.motion.R;
20 | import com.james.motion.commmon.utils.Conn;
21 | import com.james.motion.commmon.utils.MySp;
22 | import com.james.motion.commmon.utils.UIHelper;
23 | import com.james.motion.commmon.utils.Utils;
24 | import com.james.motion.ui.BaseFragment;
25 |
26 | import butterknife.BindView;
27 | import butterknife.OnClick;
28 |
29 | /**
30 | * 描述: 验证码快速登录
31 | * 作者: james
32 | * 日期: 2019/1/4 18:15
33 | * 类名: FastLoginFragment
34 | */
35 | public class FastLoginFragment extends BaseFragment {
36 |
37 | @BindView(R.id.et_phone)
38 | EditText etPhone;
39 | @BindView(R.id.et_code)
40 | EditText etCode;
41 | @BindView(R.id.btClear)
42 | ImageButton btClear;
43 | @BindView(R.id.chronometer)
44 | Chronometer chronometer;
45 |
46 | private String code = "-1";
47 |
48 | @Override
49 | public int getLayoutId() {
50 | return R.layout.fragment_fastlogin;
51 | }
52 |
53 | @Override
54 | public void initData(Bundle savedInstanceState) {
55 |
56 | String loginname = SPUtils.getInstance().getString(MySp.PHONE);
57 | String password = SPUtils.getInstance().getString(MySp.PASSWORD);
58 | if (!TextUtils.isEmpty(loginname)) {
59 | btClear.setVisibility(View.VISIBLE);
60 | etPhone.setText(loginname);
61 | }
62 |
63 | chronometer.setText("获取验证码");
64 | }
65 |
66 | @Override
67 | public void initListener() {
68 | chronometer.setOnChronometerTickListener(chronometer -> {
69 | long time = (Long) chronometer.getTag() - SystemClock.elapsedRealtime() / 1000;
70 | if (time > 0) {
71 | chronometer.setText(UIHelper.getString(R.string.chronometer_time, time));
72 | } else {
73 | chronometer.setText("重新获取");
74 | chronometer.stop();
75 | chronometer.setEnabled(true);
76 | }
77 | });
78 | etPhone.addTextChangedListener(new TextWatcher() {
79 | @Override
80 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
81 |
82 | }
83 |
84 | @Override
85 | public void onTextChanged(CharSequence s, int start, int before, int count) {
86 | btClear.setVisibility(s.length() > 0 ? View.VISIBLE : View.GONE);
87 | }
88 |
89 | @Override
90 | public void afterTextChanged(Editable s) {
91 |
92 | }
93 | });
94 | }
95 |
96 | @OnClick({R.id.chronometer, R.id.btClear})
97 | public void onViewClicked(View view) {
98 | switch (view.getId()) {
99 | case R.id.chronometer:
100 | String phone = etPhone.getText().toString();
101 | if (TextUtils.isEmpty(phone)) {
102 | ToastUtils.showShort("请输入11位手机号码");
103 | return;
104 | }
105 | if (!Utils.isMobile(phone)) {
106 | ToastUtils.showShort("请输入正确的手机号码");
107 | return;
108 | }
109 | // 先影藏输入法
110 | InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
111 | imm.hideSoftInputFromWindow(etPhone.getWindowToken(), 0);
112 |
113 | yanZhengMa();
114 |
115 | break;
116 | case R.id.btClear:
117 | etPhone.setText("");
118 | break;
119 | default:
120 | break;
121 | }
122 | }
123 |
124 | public void yzmStart() {
125 | chronometer.setTag(SystemClock.elapsedRealtime() / 1000 + 60);
126 | chronometer.setText("(60)重新获取");
127 | chronometer.start();
128 | chronometer.setEnabled(false);
129 |
130 | getActivity().getWindow()
131 | .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
132 | }
133 |
134 | /**
135 | * 获取验证码
136 | */
137 | public void yanZhengMa() {
138 | showLoadingView();
139 | new Handler().postDelayed(() -> {
140 | dismissLoadingView();
141 | int numcode = (int) ((Math.random() * 9 + 1) * 100000);
142 | code = numcode + "";
143 | yzmStart();
144 | ToastUtils.showShort("验证获取成功!");
145 | etCode.setText(code);
146 | }, Conn.Delayed);
147 | }
148 |
149 | public void checkAccount(CallBack callBack) {
150 | if (null != etPhone && null != etCode) {
151 | if (isInput(etPhone, etCode)) {
152 | String account = etPhone.getText().toString();
153 | String codes = etCode.getText().toString();
154 | if (!Utils.isMobile(account)) {
155 | ToastUtils.showShort("请输入正确的手机号码");
156 | } else if (!TextUtils.equals(codes, code)) {
157 | ToastUtils.showShort("请输入正确的验证码!");
158 | } else {
159 | callBack.getResult(account, codes);
160 | }
161 | }
162 | }
163 | }
164 |
165 | public interface CallBack {
166 | void getResult(String account, String psd);
167 | }
168 |
169 | private boolean isInput(EditText... e) {
170 | for (EditText anE : e) {
171 | if (TextUtils.isEmpty(anE.getText())) {
172 | ToastUtils.showShort(anE.getHint().toString());
173 | return false;
174 | }
175 | }
176 | return true;
177 | }
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/fragment/PsdLoginFragment.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.text.Editable;
5 | import android.text.InputType;
6 | import android.text.TextUtils;
7 | import android.text.TextWatcher;
8 | import android.view.View;
9 | import android.widget.EditText;
10 | import android.widget.ImageButton;
11 |
12 | import com.blankj.utilcode.util.SPUtils;
13 | import com.blankj.utilcode.util.ToastUtils;
14 | import com.james.motion.R;
15 | import com.james.motion.commmon.utils.MySp;
16 | import com.james.motion.ui.BaseFragment;
17 |
18 | import butterknife.BindView;
19 | import butterknife.OnClick;
20 |
21 | /**
22 | * 描述: 密码登录
23 | * 作者: james
24 | * 日期: 2019/1/4 18:15
25 | * 类名: PsdLoginFragment
26 | */
27 | public class PsdLoginFragment extends BaseFragment {
28 |
29 | @BindView(R.id.et_username)
30 | EditText etUsername;
31 | @BindView(R.id.et_psd)
32 | EditText etPsd;
33 | @BindView(R.id.btClear)
34 | ImageButton btClear;
35 | @BindView(R.id.btPsd)
36 | ImageButton btPsd;
37 |
38 | private boolean iscleartext = false;
39 |
40 | @Override
41 | public int getLayoutId() {
42 | return R.layout.fragment_psdlogin;
43 | }
44 |
45 | @Override
46 | public void initData(Bundle savedInstanceState) {
47 | String loginname = SPUtils.getInstance().getString(MySp.PHONE);
48 | String password = SPUtils.getInstance().getString(MySp.PASSWORD);
49 | if (!TextUtils.isEmpty(loginname)) {
50 | btClear.setVisibility(View.VISIBLE);
51 | etUsername.setText(loginname);
52 | }
53 | }
54 |
55 | @Override
56 | public void initListener() {
57 | etUsername.addTextChangedListener(new TextWatcher() {
58 | @Override
59 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
60 |
61 | }
62 |
63 | @Override
64 | public void onTextChanged(CharSequence s, int start, int before, int count) {
65 | btClear.setVisibility(s.length() > 0 ? View.VISIBLE : View.GONE);
66 | }
67 |
68 | @Override
69 | public void afterTextChanged(Editable s) {
70 |
71 | }
72 | });
73 | }
74 |
75 | @OnClick({R.id.btPsd, R.id.btClear, R.id.tvForget})
76 | public void onViewClicked(View view) {
77 | switch (view.getId()) {
78 | case R.id.btPsd:
79 | if (TextUtils.isEmpty(etPsd.getText())) {
80 | ToastUtils.showShort("请先输入密码!");
81 | return;
82 | }
83 | if (!iscleartext) {
84 | etPsd.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
85 | btPsd.setImageResource(R.mipmap.icon_psd_h);
86 | } else {
87 | etPsd.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
88 | btPsd.setImageResource(R.mipmap.icon_psd_s);
89 | }
90 | iscleartext = !iscleartext;
91 | etPsd.setSelection(etPsd.getText().length());
92 | break;
93 | case R.id.btClear:
94 | etUsername.setText("");
95 | break;
96 | case R.id.tvForget:
97 | ToastUtils.showShort("功能开发中...");
98 | break;
99 | default:
100 | break;
101 | }
102 | }
103 |
104 | public void checkAccount(CallBack callBack) {
105 | if (isInput(etUsername, etPsd)) {
106 | String account = etUsername.getText().toString();
107 | String psd = etPsd.getText().toString();
108 | if (psd.length() < 4) {
109 | ToastUtils.showShort("请输入正确的密码!");
110 | } else {
111 | callBack.getResult(account, psd);
112 | }
113 | }
114 | }
115 |
116 |
117 | public interface CallBack {
118 | void getResult(String account, String psd);
119 | }
120 |
121 | private boolean isInput(EditText... e) {
122 | for (EditText anE : e) {
123 | if (TextUtils.isEmpty(anE.getText())) {
124 | ToastUtils.showShort(anE.getHint().toString());
125 | return false;
126 | }
127 | }
128 | return true;
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/fragment/SportRecordDetailsFragment.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.widget.TextView;
5 |
6 | import com.james.motion.R;
7 | import com.james.motion.commmon.bean.PathRecord;
8 | import com.james.motion.sport_motion.MotionUtils;
9 | import com.james.motion.ui.BaseFragment;
10 | import com.james.motion.ui.activity.SportRecordDetailsActivity;
11 |
12 | import java.text.DecimalFormat;
13 |
14 | import butterknife.BindView;
15 |
16 | /**
17 | * 描述: 运动记录详情-详情
18 | * 作者: james
19 | * 日期: 2019/2/27 15:25
20 | * 类名: SportRecordDetailsFragment
21 | */
22 | public class SportRecordDetailsFragment extends BaseFragment {
23 |
24 | @BindView(R.id.tvDistance)
25 | TextView tvDistance;
26 | @BindView(R.id.tvDuration)
27 | TextView tvDuration;
28 | @BindView(R.id.tvSpeed)
29 | TextView tvSpeed;
30 | @BindView(R.id.tvDistribution)
31 | TextView tvDistribution;
32 | @BindView(R.id.tvCalorie)
33 | TextView tvCalorie;
34 |
35 | private PathRecord pathRecord = null;
36 |
37 | private DecimalFormat decimalFormat = new DecimalFormat("0.00");
38 | private DecimalFormat intFormat = new DecimalFormat("#");
39 |
40 | @Override
41 | public int getLayoutId() {
42 | return R.layout.fragment_sportrecorddetails;
43 | }
44 |
45 | @Override
46 | public void initData(Bundle savedInstanceState) {
47 | Bundle bundle = getArguments();
48 | if (bundle != null) {
49 | pathRecord = bundle.getParcelable(SportRecordDetailsActivity.SPORT_DATA);
50 | }
51 |
52 | if (null != pathRecord) {
53 | tvDistance.setText(decimalFormat.format(pathRecord.getDistance() / 1000d));
54 | tvDuration.setText(MotionUtils.formatseconds(pathRecord.getDuration()));
55 | tvSpeed.setText(decimalFormat.format(pathRecord.getSpeed()));
56 | tvDistribution.setText(decimalFormat.format(pathRecord.getDistribution()));
57 | tvCalorie.setText(intFormat.format(pathRecord.getCalorie()));
58 | }
59 |
60 | }
61 |
62 | @Override
63 | public void initListener() {
64 |
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/fragment/SportRecordDetailsSpeedFragment.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.widget.TextView;
5 |
6 | import com.james.motion.R;
7 | import com.james.motion.commmon.bean.PathRecord;
8 | import com.james.motion.ui.BaseFragment;
9 | import com.james.motion.ui.activity.SportRecordDetailsActivity;
10 |
11 | import java.text.DecimalFormat;
12 |
13 | import butterknife.BindView;
14 |
15 | /**
16 | * 描述: 运动记录详情-配速
17 | * 作者: james
18 | * 日期: 2019/2/27 15:25
19 | * 类名: SportRecordDetailsSpeedFragment
20 | */
21 | public class SportRecordDetailsSpeedFragment extends BaseFragment {
22 |
23 | @BindView(R.id.tvDistribution)
24 | TextView tvDistribution;
25 |
26 | private PathRecord pathRecord = null;
27 |
28 | private DecimalFormat decimalFormat = new DecimalFormat("0.00");
29 |
30 | @Override
31 | public int getLayoutId() {
32 | return R.layout.fragment_sportrecorddetailsspeed;
33 | }
34 |
35 | @Override
36 | public void initData(Bundle savedInstanceState) {
37 | Bundle bundle = getArguments();
38 | if (bundle != null) {
39 | pathRecord = bundle.getParcelable(SportRecordDetailsActivity.SPORT_DATA);
40 | }
41 |
42 | if (null != pathRecord)
43 | tvDistribution.setText(decimalFormat.format(pathRecord.getDistribution()));
44 | }
45 |
46 | @Override
47 | public void initListener() {
48 |
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/permission/APermission.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.permission;
2 |
3 | import android.app.Activity;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.core.app.ActivityCompat;
7 | import androidx.fragment.app.FragmentActivity;
8 |
9 | import com.blankj.utilcode.util.ToastUtils;
10 | import com.james.motion.commmon.utils.DeviceHelper;
11 | import com.james.motion.commmon.utils.LogUtils;
12 |
13 | import java.util.Arrays;
14 |
15 | public class APermission {
16 |
17 | private Builder builder;
18 |
19 | public static Builder builder(FragmentActivity mActivity) {
20 | return new Builder(mActivity);
21 | }
22 |
23 | public static Builder builder(Activity mActivity) {
24 | return new Builder(mActivity);
25 | }
26 |
27 | public static class Builder {
28 | private String[] permissions;
29 | private FragmentActivity mActivity;
30 | private PermissionListener permissionListener;
31 | private String tipContent = null;
32 | private int code = Permissions.PERMISSION_REQUEST_CODE;
33 |
34 | private Builder(FragmentActivity activity) {
35 | this.mActivity = activity;
36 | }
37 |
38 | private Builder(Activity activity) {
39 | this.mActivity = (FragmentActivity) activity;
40 | }
41 |
42 | public Builder setCode(int code) {
43 | this.code = code;
44 | return this;
45 | }
46 |
47 | public Builder setTipContent(String tipContent) {
48 | this.tipContent = tipContent;
49 | return this;
50 | }
51 |
52 | public Builder callBack(PermissionListener permissionListener) {
53 |
54 | this.permissionListener = permissionListener;
55 | return this;
56 | }
57 |
58 | public Builder setPermissions(String[] permissions) {
59 | LogUtils.d("permissionListener--" + "setPermissions" + Arrays.toString(permissions));
60 | this.permissions = permissions;
61 | return this;
62 | }
63 |
64 | public APermission request() {
65 | APermission axdPermission = new APermission();
66 | axdPermission.builder = this;
67 | if (!(permissions == null || permissions.length == 0)) {
68 | axdPermission.requestPermission();
69 | }
70 | if (mActivity instanceof PermissionActivity) {
71 | ((PermissionActivity) mActivity).setAxdPermission(axdPermission);
72 | }
73 | return axdPermission;
74 | }
75 | }
76 |
77 | PermissionListener getPermissionListener() {
78 | if (builder == null) {
79 | return null;
80 | }
81 | return builder.permissionListener;
82 | }
83 |
84 | private void requestPermission() {
85 | if (PermissionUtil.hasSelfPermissions(builder.mActivity, builder.permissions) || !DeviceHelper.isOverMarshmallow()) {
86 | builder.permissionListener.onPassed();
87 | } else {
88 | String[] unPassPermissions = PermissionUtil.cutPassPermissions(builder.mActivity, builder.permissions);
89 | if (unPassPermissions.length == 0) {
90 | builder.permissionListener.onPassed();
91 | return;
92 | }
93 | ActivityCompat.requestPermissions(builder.mActivity, unPassPermissions, builder.code);
94 | }
95 | }
96 |
97 | void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
98 | if ((requestCode == builder.code && PermissionUtil.verifyPermissions(grantResults))
99 | || PermissionUtil.hasSelfPermissions(builder.mActivity, builder.permissions)) {
100 | builder.permissionListener.onPassed();
101 | } else {
102 | boolean neverAsk = !PermissionUtil.shouldShowRequestPermissionRationale(builder.mActivity, permissions);
103 | if (!builder.permissionListener.onDenied(neverAsk)) {
104 | if (neverAsk) {
105 | ToastUtils.showShort("权限缺失");
106 | } else {
107 | ToastUtils.showShort("权限缺失");
108 | }
109 | }
110 |
111 | }
112 | }
113 |
114 | /**
115 | * 从设置页面返回后
116 | */
117 | public void onSettingResult(@NonNull APermission axdPermission) {
118 | axdPermission.requestPermission();
119 | }
120 |
121 | public void destroy() {
122 | builder = null;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/permission/PermissionActivity.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.permission;
2 |
3 | import android.content.Intent;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.appcompat.app.AppCompatActivity;
7 |
8 | import com.james.motion.commmon.utils.LogUtils;
9 |
10 | public abstract class PermissionActivity extends AppCompatActivity {
11 |
12 | private APermission axdPermission;
13 |
14 | public void setAxdPermission(APermission axdPermission) {
15 | this.axdPermission = axdPermission;
16 | }
17 |
18 | @Override
19 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
20 | super.onActivityResult(requestCode, resultCode, data);
21 | if (requestCode == Permissions.PERMISSION_SETTING_CODE) {
22 | onSettingResult(requestCode);
23 | }
24 | }
25 |
26 |
27 | protected void onSettingResult(int requestCode) {
28 | LogUtils.d("permission--" + "setting" + requestCode);
29 | if (axdPermission != null) {
30 | axdPermission.onSettingResult(axdPermission);
31 | }
32 | }
33 |
34 | /**
35 | * 权限请求结果
36 | */
37 | @Override
38 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
39 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
40 | if (axdPermission != null && axdPermission.getPermissionListener() != null) {
41 | axdPermission.onRequestPermissionsResult(requestCode, permissions, grantResults);
42 | }
43 | }
44 |
45 |
46 | @Override
47 | protected void onDestroy() {
48 | if (axdPermission != null) {
49 | axdPermission.destroy();
50 | axdPermission = null;
51 | }
52 | super.onDestroy();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/permission/PermissionHelper.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.permission;
2 |
3 | import android.app.Activity;
4 |
5 | public class PermissionHelper {
6 | /**
7 | * 申请权限,固定重试提示
8 | */
9 | public static void requestPermissions(Activity mActivity, String[] permission, final PermissionListener callback) {
10 | APermission.builder(mActivity)
11 | .setPermissions(permission)
12 | .callBack(callback).request();
13 | }
14 | /**
15 | * 申请权限,自定义重试提示文字
16 | */
17 | public static void requestPermissions(Activity mActivity, String[] permission, String tipContent, final PermissionListener callback) {
18 | APermission.builder(mActivity)
19 | .setPermissions(permission)
20 | .setTipContent(tipContent)
21 | .callBack(callback).request();
22 | }
23 |
24 | public static boolean hasMustPermission(Activity activity) {
25 | return PermissionUtil.hasSelfPermissions(activity, Permissions.PERMISSIONS_FIRST);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/permission/PermissionListener.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.permission;
2 |
3 | public abstract class PermissionListener {
4 | /**
5 | * 权限通过
6 | */
7 | public abstract void onPassed();
8 |
9 | /**
10 | * 权限拒绝
11 | * neverAsk: 不再询问
12 | *
13 | * @return 如果要覆盖原有提示则返回true
14 | */
15 | public boolean onDenied(boolean neverAsk) {
16 | return false;
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/permission/PermissionRetryCallBack.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.permission;
2 |
3 | public interface PermissionRetryCallBack {
4 | void onClick();
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/permission/PermissionUtil.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.permission;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.pm.PackageManager;
7 | import android.net.Uri;
8 | import android.os.Build;
9 | import android.provider.Settings;
10 |
11 | import androidx.collection.SimpleArrayMap;
12 | import androidx.core.app.ActivityCompat;
13 | import androidx.core.content.ContextCompat;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | /**
19 | * 权限工具类
20 | */
21 | public final class PermissionUtil {
22 |
23 |
24 | private static final SimpleArrayMap MIN_SDK_PERMISSIONS;
25 |
26 | static {
27 | MIN_SDK_PERMISSIONS = new SimpleArrayMap<>(8);
28 | MIN_SDK_PERMISSIONS.put("com.android.voicemail.permission.ADD_VOICEMAIL", 14);
29 | MIN_SDK_PERMISSIONS.put("android.permission.BODY_SENSORS", 20);
30 | MIN_SDK_PERMISSIONS.put("android.permission.READ_CALL_LOG", 16);
31 | MIN_SDK_PERMISSIONS.put("android.permission.READ_EXTERNAL_STORAGE", 16);
32 | MIN_SDK_PERMISSIONS.put("android.permission.USE_SIP", 9);
33 | MIN_SDK_PERMISSIONS.put("android.permission.WRITE_CALL_LOG", 16);
34 | MIN_SDK_PERMISSIONS.put("android.permission.SYSTEM_ALERT_WINDOW", 23);
35 | MIN_SDK_PERMISSIONS.put("android.permission.WRITE_SETTINGS", 23);
36 | }
37 |
38 | /**
39 | * 检测所有权限是否通过
40 | */
41 | public static boolean verifyPermissions(int... grantResults) {
42 | if (grantResults.length == 0) {
43 | return false;
44 | }
45 | for (int result : grantResults) {
46 | if (result != PackageManager.PERMISSION_GRANTED) {
47 | return false;
48 | }
49 | }
50 | return true;
51 | }
52 |
53 | /**
54 | * 检测是否拥有全部权限
55 | */
56 | public static boolean hasSelfPermissions(Context context, String... permissions) {
57 | for (String permission : permissions) {
58 | if (!hasSelfPermission(context, permission)) {
59 | return false;
60 | }
61 | }
62 | return true;
63 | }
64 |
65 | /**
66 | * 检测在某版本中是否存在该权限
67 | */
68 | private static boolean permissionExists(String permission) {
69 | Integer minVersion = MIN_SDK_PERMISSIONS.get(permission);
70 |
71 | return minVersion == null || Build.VERSION.SDK_INT >= minVersion;
72 | }
73 |
74 | /**
75 | * 是否拥有该权限
76 | */
77 | public static boolean hasSelfPermission(Context context, String permission) {
78 | try {
79 | return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
80 | } catch (RuntimeException t) {
81 | return false;
82 | }
83 | }
84 |
85 | /**
86 | * 检测是否有权限一直被拒绝
87 | */
88 | public static boolean shouldShowRequestPermissionRationale(Activity activity, String... permissions) {
89 | for (String permission : permissions) {
90 | if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
91 | return true;
92 | }
93 | }
94 | return false;
95 | }
96 |
97 | /**
98 | * 过滤掉已经申请通过的权限
99 | */
100 | public static String[] cutPassPermissions(Activity activity, String[] permissions) {
101 | List stringList = new ArrayList<>();
102 | for (String permission : permissions) {
103 | if (!hasSelfPermission(activity, permission)) {
104 | stringList.add(permission);
105 | }
106 | }
107 | String strings[] = new String[stringList.size()];
108 | for (int i = 0, j = stringList.size(); i < j; i++) {
109 | strings[i] = stringList.get(i);
110 | }
111 | return strings;
112 | }
113 |
114 | /**
115 | * 启动应用的设置
116 | */
117 | public static void startAppSettings(Activity activity, int requestCode) {
118 | Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
119 | Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
120 | intent.setData(uri);
121 | activity.startActivityForResult(intent, requestCode);
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/permission/Permissions.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.permission;
2 |
3 | import android.Manifest;
4 |
5 | public interface Permissions {
6 | /**
7 | * 权限申请CODE
8 | */
9 | int PERMISSION_REQUEST_CODE = 400;
10 |
11 | int PERMISSION_SETTING_CODE = 401;
12 |
13 | /**
14 | * 进入app请求的权限
15 | */
16 | String[] PERMISSIONS_FIRST = new String[]{
17 | Manifest.permission.READ_PHONE_STATE,
18 | Manifest.permission.READ_EXTERNAL_STORAGE,
19 | };
20 | String[] PERMISSIONS_HOME = new String[]{
21 | Manifest.permission.READ_CONTACTS,
22 | Manifest.permission.ACCESS_FINE_LOCATION
23 | };
24 | String[] PERMISSIONS_BIOSPSY_AUDIO = new String[]{
25 | Manifest.permission.CAMERA,
26 | Manifest.permission.RECORD_AUDIO,
27 | Manifest.permission.READ_EXTERNAL_STORAGE
28 | };
29 | String[] PERMISSIONS_BIOSPSY = new String[]{
30 | Manifest.permission.CAMERA,
31 | Manifest.permission.READ_EXTERNAL_STORAGE
32 | };
33 | String[] PERMISSIONS_PHONE_STATE = new String[]{
34 | Manifest.permission.READ_PHONE_STATE
35 | };
36 | String[] PERMISSIONS_CAMERA = new String[]{
37 | Manifest.permission.CAMERA,
38 | Manifest.permission.RECORD_AUDIO,
39 | Manifest.permission.WRITE_EXTERNAL_STORAGE,
40 | Manifest.permission.READ_EXTERNAL_STORAGE
41 | };
42 | String[] PERMISSIONS_GALLERY = new String[]{
43 | Manifest.permission.READ_EXTERNAL_STORAGE,
44 | Manifest.permission.WRITE_EXTERNAL_STORAGE
45 | };
46 | String[] PERMISSIONS_RECORD_AUDIO = new String[]{
47 | Manifest.permission.RECORD_AUDIO,
48 | Manifest.permission.WRITE_EXTERNAL_STORAGE,
49 | Manifest.permission.WAKE_LOCK,
50 | Manifest.permission.READ_EXTERNAL_STORAGE
51 | };
52 | String[] PERMISSIONS_SMS = new String[]{
53 | Manifest.permission.READ_SMS,
54 | Manifest.permission.SEND_SMS
55 | };
56 | String[] PERMISSIONS_CONTACTS = {
57 | Manifest.permission.READ_CONTACTS,
58 | Manifest.permission.WRITE_CONTACTS};
59 | String[] PERMISSIONS_LOCATION = new String[]{
60 | Manifest.permission.ACCESS_FINE_LOCATION,
61 | Manifest.permission.ACCESS_COARSE_LOCATION
62 | };
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/weight/AMapScrollViewPager.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.weight;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 |
7 | import androidx.viewpager.widget.ViewPager;
8 |
9 | /**
10 | * 描述: 重写ViewPager canScroll方法,解决ViewPager和地图横向滑动冲突
11 | * 作者: james
12 | * 日期: 2019/2/27 15:16
13 | * 类名: AMapScrollViewPager
14 | */
15 | public class AMapScrollViewPager extends ViewPager {
16 |
17 | public AMapScrollViewPager(Context context) {
18 | super(context);
19 | }
20 |
21 | public AMapScrollViewPager(Context context, AttributeSet attrs) {
22 | super(context, attrs);
23 | }
24 |
25 | @Override
26 | public boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
27 | if (Math.abs(dx) > 50) {
28 | return super.canScroll(v, checkV, dx, x, y);
29 | } else {
30 | return true;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/weight/CustomProgressDialog.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.weight;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.WindowManager;
9 |
10 | import com.james.motion.R;
11 |
12 | /**
13 | * @describe 自定义进度条
14 | */
15 | public class CustomProgressDialog extends Dialog {
16 |
17 | private Context mContext;
18 |
19 | public CustomProgressDialog(final Context context) {
20 | // TODO Auto-generated constructor stub
21 | super(context, R.style.customProgressDialog);
22 | this.mContext = context;
23 |
24 | // 设置点击进度条外部取消
25 | this.setCanceledOnTouchOutside(false);
26 | // 设置点击进度可以取消
27 | this.setCancelable(false);
28 |
29 | setTouchAble(true);
30 | }
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
36 |
37 | View rootView = LayoutInflater.from(mContext).inflate(R.layout.custom_progress_dialog_layout, null);
38 |
39 | setContentView(rootView);
40 | }
41 |
42 | /**
43 | * 设置是否可点击下一层 true:可点击 false:不可点击 默认是可点击
44 | *
45 | * @param isTouchAble
46 | */
47 | public void setTouchAble(boolean isTouchAble) {
48 |
49 | if (isTouchAble) {
50 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
51 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
52 |
53 | //显示阴影
54 | WindowManager.LayoutParams lp = getWindow().getAttributes();
55 | lp.dimAmount = 0.3f;
56 | getWindow().setAttributes(lp);
57 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
58 |
59 | //不显示阴影
60 | // getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
61 |
62 | } else {
63 | getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
64 | WindowManager.LayoutParams lp = getWindow().getAttributes();
65 | lp.dimAmount = 0.3f;
66 | getWindow().setAttributes(lp);
67 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
68 | }
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/weight/calendarview/custom/CustomWeekBar.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.weight.calendarview.custom;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.view.LayoutInflater;
6 | import android.widget.TextView;
7 |
8 | import com.haibin.calendarview.Calendar;
9 | import com.haibin.calendarview.WeekBar;
10 | import com.james.motion.R;
11 |
12 | /**
13 | * 自定义英文栏
14 | */
15 | public class CustomWeekBar extends WeekBar {
16 |
17 | private int mPreSelectedIndex;
18 |
19 | public CustomWeekBar(Context context) {
20 | super(context);
21 | LayoutInflater.from(context).inflate(R.layout.custom_week_bar, this, true);
22 | setBackgroundColor(Color.WHITE);
23 | }
24 |
25 | @Override
26 | protected void onDateSelected(Calendar calendar, int weekStart, boolean isClick) {
27 | getChildAt(mPreSelectedIndex).setSelected(false);
28 | int viewIndex = getViewIndexByCalendar(calendar, weekStart);
29 | getChildAt(viewIndex).setSelected(true);
30 | mPreSelectedIndex = viewIndex;
31 | }
32 |
33 | /**
34 | * 当周起始发生变化,使用自定义布局需要重写这个方法,避免出问题
35 | *
36 | * @param weekStart 周起始
37 | */
38 | @Override
39 | protected void onWeekStartChange(int weekStart) {
40 | for (int i = 0; i < getChildCount(); i++) {
41 | ((TextView) getChildAt(i)).setText(getWeekString(i, weekStart));
42 | }
43 | }
44 |
45 | /**
46 | * 或者周文本,这个方法仅供父类使用
47 | * @param index index
48 | * @param weekStart weekStart
49 | * @return 或者周文本
50 | */
51 | private String getWeekString(int index, int weekStart) {
52 | String[] weeks = getContext().getResources().getStringArray(R.array.chinese_week_string_array);
53 |
54 | if (weekStart == 1) {
55 | return weeks[index];
56 | }
57 | if (weekStart == 2) {
58 | return weeks[index == 6 ? 0 : index + 1];
59 | }
60 | return weeks[index == 0 ? 6 : index - 1];
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/james/motion/ui/weight/calendarview/custom/CustomYearView.java:
--------------------------------------------------------------------------------
1 | package com.james.motion.ui.weight.calendarview.custom;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 |
7 | import com.haibin.calendarview.Calendar;
8 | import com.haibin.calendarview.YearView;
9 | import com.james.motion.R;
10 |
11 | /**
12 | * 自定义年视图
13 | */
14 | public class CustomYearView extends YearView {
15 |
16 | private int mTextPadding;
17 | /**
18 | * 闰年字体
19 | */
20 | private Paint mLeapYearTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
21 |
22 | public CustomYearView(Context context) {
23 | super(context);
24 | mTextPadding = dipToPx(context, 3);
25 |
26 | mLeapYearTextPaint.setTextSize(dipToPx(context, 12));
27 | mLeapYearTextPaint.setColor(0xffd1d1d1);
28 | mLeapYearTextPaint.setAntiAlias(true);
29 | mLeapYearTextPaint.setFakeBoldText(true);
30 |
31 | }
32 |
33 | @Override
34 | protected void onDrawMonth(Canvas canvas, int year, int month, int x, int y, int width, int height) {
35 |
36 | String text = getContext()
37 | .getResources()
38 | .getStringArray(R.array.month_string_array)[month - 1];
39 | canvas.drawText(text,
40 | x + mItemWidth / 2 - mTextPadding,
41 | y + mMonthTextBaseLine,
42 | mMonthTextPaint);
43 | if (month == 2 && isLeapYear(year)) {
44 | float w = getTextWidth(mMonthTextPaint, text);
45 |
46 | canvas.drawText("闰年",
47 | x + mItemWidth / 2 - mTextPadding + w + dipToPx(getContext(), 6),
48 | y + mMonthTextBaseLine,
49 | mLeapYearTextPaint);
50 | }
51 | }
52 |
53 | private float getTextWidth(Paint paint, String text) {
54 | return paint.measureText(text);
55 | }
56 |
57 | /**
58 | * 是否是闰年
59 | *
60 | * @param year year
61 | * @return 是否是闰年
62 | */
63 | private static boolean isLeapYear(int year) {
64 | return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
65 | }
66 |
67 |
68 | @Override
69 | protected void onDrawWeek(Canvas canvas, int week, int x, int y, int width, int height) {
70 | String text = getContext().getResources().getStringArray(R.array.year_view_week_string_array)[week];
71 | canvas.drawText(text,
72 | x + width / 2,
73 | y + mWeekTextBaseLine,
74 | mWeekTextPaint);
75 | }
76 |
77 |
78 | @Override
79 | protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme) {
80 | int cx = x + mItemWidth / 2;
81 | int cy = y + mItemHeight / 2;
82 | int radius = Math.min(mItemWidth, mItemHeight) / 8 * 5;
83 | canvas.drawCircle(cx, cy, radius, mSelectedPaint);
84 | return true;
85 | }
86 |
87 | @Override
88 | protected void onDrawScheme(Canvas canvas, Calendar calendar, int x, int y) {
89 |
90 | }
91 |
92 | @Override
93 | protected void onDrawText(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme, boolean isSelected) {
94 | float baselineY = mTextBaseLine + y;
95 | int cx = x + mItemWidth / 2;
96 |
97 | if (isSelected) {
98 | canvas.drawText(String.valueOf(calendar.getDay()),
99 | cx,
100 | baselineY,
101 | hasScheme ? mSchemeTextPaint : mSelectTextPaint);
102 | } else if (hasScheme) {
103 | canvas.drawText(String.valueOf(calendar.getDay()),
104 | cx,
105 | baselineY,
106 | calendar.isCurrentDay() ? mCurDayTextPaint : mSchemeTextPaint);
107 |
108 | } else {
109 | canvas.drawText(String.valueOf(calendar.getDay()), cx, baselineY,
110 | calendar.isCurrentDay() ? mCurDayTextPaint : mCurMonthTextPaint);
111 | }
112 | }
113 |
114 | /**
115 | * dp转px
116 | *
117 | * @param context context
118 | * @param dpValue dp
119 | * @return px
120 | */
121 | private static int dipToPx(Context context, float dpValue) {
122 | final float scale = context.getResources().getDisplayMetrics().density;
123 | return (int) (dpValue * scale + 0.5f);
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_left_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_left_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_right_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_right_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/mylocation_point.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/drawable-hdpi/mylocation_point.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/bg_ripple.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/back_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/back_selector_n.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/back_selector_p.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_edittext.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_gray_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_green_box_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_green_box_selector_n.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_green_box_selector_p.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_green_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_green_selector_n.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_green_selector_p.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_nor_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_white_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_white_selector_n.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_white_selector_p.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/et_coner_box_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/et_coner_white_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/et_underline.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/green_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/layer_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | -
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/loadind_dialog_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sport_change_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sport_end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/drawable/sport_end.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sport_start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/drawable/sport_start.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sport_walk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/drawable/sport_walk.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sport_white_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
21 |
22 |
34 |
35 |
36 |
37 |
42 |
43 |
49 |
50 |
57 |
58 |
59 |
67 |
68 |
73 |
74 |
80 |
81 |
89 |
90 |
96 |
97 |
98 |
104 |
105 |
111 |
112 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
24 |
25 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_sportrecorddetails.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
23 |
24 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/adapter_sportcalendar.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
28 |
29 |
36 |
37 |
38 |
39 |
45 |
46 |
53 |
54 |
61 |
62 |
63 |
64 |
70 |
71 |
78 |
79 |
86 |
87 |
88 |
89 |
90 |
91 |
99 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_progress_dialog_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_week_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
25 |
26 |
34 |
35 |
43 |
44 |
52 |
53 |
61 |
62 |
70 |
71 |
80 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_fastlogin.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
18 |
19 |
25 |
26 |
41 |
42 |
51 |
52 |
53 |
60 |
61 |
67 |
68 |
82 |
83 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_psdlogin.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
18 |
19 |
25 |
26 |
41 |
42 |
51 |
52 |
53 |
59 |
60 |
66 |
67 |
81 |
82 |
89 |
90 |
91 |
101 |
102 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sportrecorddetailsmap.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
20 |
21 |
30 |
31 |
39 |
40 |
49 |
50 |
51 |
52 |
59 |
60 |
64 |
65 |
72 |
73 |
79 |
80 |
81 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sportrecorddetailsspeed.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_sport_result_tip.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
20 |
21 |
27 |
28 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
17 |
18 |
24 |
25 |
32 |
33 |
34 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tip_dialog_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
27 |
28 |
29 |
37 |
38 |
47 |
48 |
49 |
50 |
54 |
55 |
61 |
62 |
73 |
74 |
78 |
79 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/app_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/big_no_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/big_no_star.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/big_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/big_star.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/gps_point.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/gps_point.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_account.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_account.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_back_white.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_code.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_code_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_code_white.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_et_del.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_et_del.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_help.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_phone_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_phone_white.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_psd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_psd.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_psd_ck_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_psd_ck_white.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_psd_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_psd_h.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_psd_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_psd_s.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_psd_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_psd_white.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_qq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_qq.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_sport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_sport.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_tip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_tip.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_user.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_wc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/icon_wc.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/map_mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/map_mode.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/run_mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/run_mode.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/small_no_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/small_no_star.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/small_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/small_star.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/sport_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/sport_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/sport_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/sport_mark.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/star_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xhdpi/star_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/login_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xxhdpi/login_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/splash_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xxhdpi/splash_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xxhdpi/start.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/app/src/main/res/mipmap-xxxhdpi/ic_calendar.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v19/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 24dp
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #40c632
6 |
7 |
8 | #49B557
9 | #57df48
10 | #40c632
11 |
12 |
13 | #f8f9fa
14 | #FFFFFF
15 | #FF0000
16 | #000000
17 | #00000000
18 | #FFFFFF
19 | #000000
20 | #333333
21 | #666666
22 | #999999
23 | #DDDDDD
24 | #477be5
25 | #FF6D6D
26 | #6BC4A2
27 | #eeb60e
28 | #DEDEDE
29 | #ffe8e8e8
30 | #00000000
31 |
32 | #45C01A
33 | #45C01A
34 | #A3DEA3
35 | #1AAD19
36 |
37 | #D4D4D4
38 | #464646
39 | #7e7e7e
40 | #969696
41 | #c8969696
42 | #F5F5F5
43 | #EBEBEB
44 | #FBFBFB
45 | #999999
46 | #D9D9D9
47 | #DBDFE0
48 | #ffbebebe
49 |
50 | #0ba78c
51 | #550ba78c
52 | #280ba78c
53 |
54 | #49B557
55 | #01BF71
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 18sp
6 | 10sp
7 | 11sp
8 | 12sp
9 | 13sp
10 | 14sp
11 | 15sp
12 | 16sp
13 | 17sp
14 | 18sp
15 |
16 |
17 | 49dp
18 | 0.7dp
19 | 45dp
20 | 48dp
21 |
22 |
23 | 4dp
24 | 0.5dp
25 | 15dp
26 | 20dp
27 | 10dp
28 | 3dp
29 | 1dp
30 | 0dp
31 | 3dp
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/values/layout_styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
15 |
16 |
17 |
30 |
31 |
32 |
46 |
47 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Motion
3 |
4 | Android V%1$s
5 |
6 | 0123456789qwertyuiopasdfghjklzxcvbnmZXCVBNMLKJHGFDSAQWERTYUIOP
7 |
8 | (%s)重新获取
9 |
10 | %1$s月%2$s日
11 | %1$s-%2$s-%3$s
12 | %1$s:%2$s
13 |
14 |
15 | - 周日
16 | - 周一
17 | - 周二
18 | - 周三
19 | - 周四
20 | - 周五
21 | - 周六
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
17 |
18 |
19 |
25 |
26 |
27 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | apply from: "config.gradle"
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.5.1'
11 | classpath "io.realm:realm-gradle-plugin:5.9.1"
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 | maven { url "https://jitpack.io" }
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/config.gradle:
--------------------------------------------------------------------------------
1 | ext {
2 | //android开发版本配置
3 | android = [
4 | compileSdkVersion: 29,
5 | buildToolsVersion: "29.0.2",
6 | applicationId : "com.james.motion",
7 | minSdkVersion : 19,
8 | targetSdkVersion : 29,
9 | versionCode : 1,
10 | versionName : "1.0",
11 | java_version : JavaVersion.VERSION_1_8,
12 | ]
13 | //version配置
14 | versions = [
15 | "appcompat-version" : "1.1.0",
16 | "annotation-version" : "1.1.0",
17 | "recyclerview-version" : "1.1.0-beta04",
18 | "swiperefreshlayout-version": "1.0.0",
19 | "cardview-version" : "1.0.0",
20 | "layout-version" : "1.1.3",
21 | "design-version" : "1.1.0-alpha10",
22 | "junit-version" : "4.12",
23 | "test_ext" : "1.1.1",
24 | "test_espresso" : "3.2.0",
25 | ]
26 | //support配置
27 | support = [
28 | 'appcompat' : "androidx.appcompat:appcompat:${versions["appcompat-version"]}",
29 | 'annotation' : "androidx.annotation:annotation:${versions["annotation-version"]}",
30 | 'recyclerview' : "androidx.recyclerview:recyclerview:${versions["recyclerview-version"]}",
31 | 'swiperefreshlayout' : "androidx.swiperefreshlayout:swiperefreshlayout:${versions["swiperefreshlayout-version"]}",
32 | 'cardview' : "androidx.cardview:cardview:${versions["cardview-version"]}",
33 | 'layout' : "androidx.constraintlayout:constraintlayout:${versions["layout-version"]}",
34 | 'design' : "com.google.android.material:material:${versions["design-version"]}",
35 | 'testImplementation' : "junit:junit:${versions["junit-version"]}",
36 | 'androidtestimplementation_ext' : "androidx.test.ext:junit:${versions["test_ext"]}",
37 | 'androidtestimplementation_espresso': "androidx.test.espresso:espresso-core:${versions["test_espresso"]}",
38 | ]
39 | //依赖第三方配置
40 | dependencies = [
41 | //json解析
42 | "gson" : "com.google.code.gson:gson:2.8.5",
43 | //butterknife
44 | butterknife_api : "com.jakewharton:butterknife:10.1.0",
45 | annotationProcessor : "com.jakewharton:butterknife-compiler:10.1.0",
46 | //RecycleVierw-Adapter
47 | recyclevierw_adapter : "com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.47",
48 | //utilcode
49 | utilcode : "com.blankj:utilcode:1.21.0",
50 | //calendarview
51 | calendarview : "com.haibin:calendarview:3.5.4",
52 | //沉浸式适配
53 | immersionbar : "com.gyf.immersionbar:immersionbar:3.0.0",
54 | immersionbar_components : "com.gyf.immersionbar:immersionbar-components:3.0.0",
55 | //FlycoTabLayout_Lib
56 | flycotablayout_lib : "com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar",
57 |
58 | //地图
59 | Map_3D : "com.amap.api:3dmap:latest.integration",
60 | Map_search : "com.amap.api:search:latest.integration",
61 | Map_location : "com.amap.api:location:latest.integration",
62 |
63 | // 内存泄漏检测
64 | leakcanary_debug : "com.squareup.leakcanary:leakcanary-android:1.6.3",
65 | leakcanary_release : "com.squareup.leakcanary:leakcanary-android-no-op:1.6.3",
66 | leakcanary_debug_fragmen: "com.squareup.leakcanary:leakcanary-support-fragment:1.6.3",
67 | ]
68 | }
69 |
70 |
71 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 |
21 |
22 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aqx1991/Motion/0368b18db1b63425a9139e89320075100ac7cc59/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Feb 25 15:20:52 CST 2019
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-5.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
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 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------