├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── AndroidUtils.iml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── hjx │ │ └── androidutils │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── utils │ │ ├── AppUtil.java │ │ ├── ColorsUtil.java │ │ ├── DateUtil.java │ │ ├── DensityUtil.java │ │ ├── ExitActivityUtil.java │ │ ├── FileUtil.java │ │ ├── HttpUtil.java │ │ ├── LogUtil.java │ │ ├── NetUtil.java │ │ ├── PhoneUtil.java │ │ ├── SDCardUtil.java │ │ ├── SPUtil.java │ │ ├── ScreenUtil.java │ │ ├── ShortCutUtil.java │ │ ├── StringUtil.java │ │ ├── ToastUtil.java │ │ └── view │ │ └── CheckBoxView.java │ └── res │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ ├── check.png │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── attrs.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .idea -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | AndroidUtils -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /AndroidUtils.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AndroidUtils 2 | 3 | AndroidUtils Use 4 | 5 | Step 1. Add the JitPack repository to your build file 6 | Add it in your root build.gradle at the end of repositories: 7 | 8 | ``` bash 9 | allprojects { 10 | repositories { 11 | ... 12 | maven { url "https://jitpack.io" } 13 | } 14 | } 15 | ``` 16 | 17 | Step 2. Add the dependency 18 | 19 | ``` bash 20 | dependencies { 21 | ... 22 | compile 'com.github.HJXANDHMR:AndroidUtils:1.2.0' 23 | } 24 | 25 | ``` 26 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | 4 | group='com.github.HJXANDHMR' 5 | 6 | android { 7 | compileSdkVersion 23 8 | buildToolsVersion '24.0.0' 9 | 10 | defaultConfig { 11 | minSdkVersion 15 12 | targetSdkVersion 23 13 | versionCode 1 14 | versionName "1.0" 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | compile fileTree(include: ['*.jar'], dir: 'libs') 26 | testCompile 'junit:junit:4.12' 27 | compile 'com.android.support:appcompat-v7:23.1.1' 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in H:\Android\adt-bundle-windows-x86_64-20140702\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/hjx/androidutils/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.example.hjx.androidutils; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/java/utils/AppUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.content.Context; 4 | import android.content.pm.PackageInfo; 5 | import android.content.pm.PackageManager; 6 | 7 | /** 8 | * app相关辅助类 9 | */ 10 | public class AppUtil { 11 | private AppUtil() { 12 | 13 | /* cannot be instantiated*/ 14 | throw new UnsupportedOperationException("cannot be instantiated"); 15 | } 16 | 17 | /** 18 | * 获取应用程序名称 19 | * 20 | * @param context 21 | * @return 22 | */ 23 | public static String getAppName(Context context) { 24 | 25 | PackageManager packageManager = context.getPackageManager(); 26 | try { 27 | PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); 28 | int labelRes = packageInfo.applicationInfo.labelRes; 29 | return context.getResources().getString(labelRes); 30 | } catch (PackageManager.NameNotFoundException e) { 31 | e.printStackTrace(); 32 | } 33 | return null; 34 | } 35 | 36 | /** 37 | * 获取应用程序版本名称信息 38 | * 39 | * @param context 40 | * @return 当前应用的版本名称 41 | */ 42 | public static String getVersionName(Context context) { 43 | try { 44 | PackageManager packageManager = context.getPackageManager(); 45 | PackageInfo packageInfo = packageManager.getPackageInfo( 46 | context.getPackageName(), 0); 47 | return packageInfo.versionName; 48 | } catch (PackageManager.NameNotFoundException e) { 49 | e.printStackTrace(); 50 | } 51 | return null; 52 | } 53 | 54 | /** 55 | * 获取应用程序的版本Code信息 56 | * @param context 57 | * @return 版本code 58 | */ 59 | public static int getVersionCode(Context context) { 60 | try { 61 | PackageManager packageManager = context.getPackageManager(); 62 | PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); 63 | return packageInfo.versionCode; 64 | } catch (PackageManager.NameNotFoundException e) { 65 | e.printStackTrace(); 66 | } 67 | return 0; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/utils/ColorsUtil.java: -------------------------------------------------------------------------------- 1 | 2 | package utils; 3 | 4 | /** 5 | * 颜色工具类 包括常用的色值 6 | */ 7 | 8 | public final class ColorsUtil { 9 | 10 | /** 11 | * Don't let anyone instantiate this class. 12 | */ 13 | private ColorsUtil() { 14 | throw new Error("Do not need instantiate!"); 15 | } 16 | 17 | /** 18 | * 白色 19 | */ 20 | public static final int WHITE = 0xffffffff; 21 | 22 | /** 23 | * 白色 - 半透明 24 | */ 25 | public static final int WHITE_TRANSLUCENT = 0x80ffffff; 26 | 27 | /** 28 | * 黑色 29 | */ 30 | public static final int BLACK = 0xff000000; 31 | 32 | /** 33 | * 黑色 - 半透明 34 | */ 35 | public static final int BLACK_TRANSLUCENT = 0x80000000; 36 | 37 | /** 38 | * 透明 39 | */ 40 | public static final int TRANSPARENT = 0x00000000; 41 | 42 | /** 43 | * 红色 44 | */ 45 | public static final int RED = 0xffff0000; 46 | 47 | /** 48 | * 红色 - 半透明 49 | */ 50 | public static final int RED_TRANSLUCENT = 0x80ff0000; 51 | 52 | /** 53 | * 红色 - 深的 54 | */ 55 | public static final int RED_DARK = 0xff8b0000; 56 | 57 | /** 58 | * 红色 - 深的 - 半透明 59 | */ 60 | public static final int RED_DARK_TRANSLUCENT = 0x808b0000; 61 | 62 | /** 63 | * 绿色 64 | */ 65 | public static final int GREEN = 0xff00ff00; 66 | 67 | /** 68 | * 绿色 - 半透明 69 | */ 70 | public static final int GREEN_TRANSLUCENT = 0x8000ff00; 71 | 72 | /** 73 | * 绿色 - 深的 74 | */ 75 | public static final int GREEN_DARK = 0xff003300; 76 | 77 | /** 78 | * 绿色 - 深的 - 半透明 79 | */ 80 | public static final int GREEN_DARK_TRANSLUCENT = 0x80003300; 81 | 82 | /** 83 | * 绿色 - 浅的 84 | */ 85 | public static final int GREEN_LIGHT = 0xffccffcc; 86 | 87 | /** 88 | * 绿色 - 浅的 - 半透明 89 | */ 90 | public static final int GREEN_LIGHT_TRANSLUCENT = 0x80ccffcc; 91 | 92 | /** 93 | * 蓝色 94 | */ 95 | public static final int BLUE = 0xff0000ff; 96 | 97 | /** 98 | * 蓝色 - 半透明 99 | */ 100 | public static final int BLUE_TRANSLUCENT = 0x800000ff; 101 | 102 | /** 103 | * 蓝色 - 深的 104 | */ 105 | public static final int BLUE_DARK = 0xff00008b; 106 | 107 | /** 108 | * 蓝色 - 深的 - 半透明 109 | */ 110 | public static final int BLUE_DARK_TRANSLUCENT = 0x8000008b; 111 | 112 | /** 113 | * 蓝色 - 浅的 114 | */ 115 | public static final int BLUE_LIGHT = 0xff36a5E3; 116 | 117 | /** 118 | * 蓝色 - 浅的 - 半透明 119 | */ 120 | public static final int BLUE_LIGHT_TRANSLUCENT = 0x8036a5E3; 121 | 122 | /** 123 | * 天蓝 124 | */ 125 | public static final int SKYBLUE = 0xff87ceeb; 126 | 127 | /** 128 | * 天蓝 - 半透明 129 | */ 130 | public static final int SKYBLUE_TRANSLUCENT = 0x8087ceeb; 131 | 132 | /** 133 | * 天蓝 - 深的 134 | */ 135 | public static final int SKYBLUE_DARK = 0xff00bfff; 136 | 137 | /** 138 | * 天蓝 - 深的 - 半透明 139 | */ 140 | public static final int SKYBLUE_DARK_TRANSLUCENT = 0x8000bfff; 141 | 142 | /** 143 | * 天蓝 - 浅的 144 | */ 145 | public static final int SKYBLUE_LIGHT = 0xff87cefa; 146 | 147 | /** 148 | * 天蓝 - 浅的 - 半透明 149 | */ 150 | public static final int SKYBLUE_LIGHT_TRANSLUCENT = 0x8087cefa; 151 | 152 | /** 153 | * 灰色 154 | */ 155 | public static final int GRAY = 0xff969696; 156 | 157 | /** 158 | * 灰色 - 半透明 159 | */ 160 | public static final int GRAY_TRANSLUCENT = 0x80969696; 161 | 162 | /** 163 | * 灰色 - 深的 164 | */ 165 | public static final int GRAY_DARK = 0xffa9a9a9; 166 | 167 | /** 168 | * 灰色 - 深的 - 半透明 169 | */ 170 | public static final int GRAY_DARK_TRANSLUCENT = 0x80a9a9a9; 171 | 172 | /** 173 | * 灰色 - 暗的 174 | */ 175 | public static final int GRAY_DIM = 0xff696969; 176 | 177 | /** 178 | * 灰色 - 暗的 - 半透明 179 | */ 180 | public static final int GRAY_DIM_TRANSLUCENT = 0x80696969; 181 | 182 | /** 183 | * 灰色 - 浅的 184 | */ 185 | public static final int GRAY_LIGHT = 0xffd3d3d3; 186 | 187 | /** 188 | * 灰色 - 浅的 - 半透明 189 | */ 190 | public static final int GRAY_LIGHT_TRANSLUCENT = 0x80d3d3d3; 191 | 192 | /** 193 | * 橙色 194 | */ 195 | public static final int ORANGE = 0xffffa500; 196 | 197 | /** 198 | * 橙色 - 半透明 199 | */ 200 | public static final int ORANGE_TRANSLUCENT = 0x80ffa500; 201 | 202 | /** 203 | * 橙色 - 深的 204 | */ 205 | public static final int ORANGE_DARK = 0xffff8800; 206 | 207 | /** 208 | * 橙色 - 深的 - 半透明 209 | */ 210 | public static final int ORANGE_DARK_TRANSLUCENT = 0x80ff8800; 211 | 212 | /** 213 | * 橙色 - 浅的 214 | */ 215 | public static final int ORANGE_LIGHT = 0xffffbb33; 216 | 217 | /** 218 | * 橙色 - 浅的 - 半透明 219 | */ 220 | public static final int ORANGE_LIGHT_TRANSLUCENT = 0x80ffbb33; 221 | 222 | /** 223 | * 金色 224 | */ 225 | public static final int GOLD = 0xffffd700; 226 | 227 | /** 228 | * 金色 - 半透明 229 | */ 230 | public static final int GOLD_TRANSLUCENT = 0x80ffd700; 231 | 232 | /** 233 | * 粉色 234 | */ 235 | public static final int PINK = 0xffffc0cb; 236 | 237 | /** 238 | * 粉色 - 半透明 239 | */ 240 | public static final int PINK_TRANSLUCENT = 0x80ffc0cb; 241 | 242 | /** 243 | * 紫红色 244 | */ 245 | public static final int FUCHSIA = 0xffff00ff; 246 | 247 | /** 248 | * 紫红色 - 半透明 249 | */ 250 | public static final int FUCHSIA_TRANSLUCENT = 0x80ff00ff; 251 | 252 | /** 253 | * 灰白色 254 | */ 255 | public static final int GRAYWHITE = 0xfff2f2f2; 256 | 257 | /** 258 | * 灰白色 - 半透明 259 | */ 260 | public static final int GRAYWHITE_TRANSLUCENT = 0x80f2f2f2; 261 | 262 | /** 263 | * 紫色 264 | */ 265 | public static final int PURPLE = 0xff800080; 266 | 267 | /** 268 | * 紫色 - 半透明 269 | */ 270 | public static final int PURPLE_TRANSLUCENT = 0x80800080; 271 | 272 | /** 273 | * 青色 274 | */ 275 | public static final int CYAN = 0xff00ffff; 276 | 277 | /** 278 | * 青色 - 半透明 279 | */ 280 | public static final int CYAN_TRANSLUCENT = 0x8000ffff; 281 | 282 | /** 283 | * 青色 - 深的 284 | */ 285 | public static final int CYAN_DARK = 0xff008b8b; 286 | 287 | /** 288 | * 青色 - 深的 - 半透明 289 | */ 290 | public static final int CYAN_DARK_TRANSLUCENT = 0x80008b8b; 291 | 292 | /** 293 | * 黄色 294 | */ 295 | public static final int YELLOW = 0xffffff00; 296 | 297 | /** 298 | * 黄色 - 半透明 299 | */ 300 | public static final int YELLOW_TRANSLUCENT = 0x80ffff00; 301 | 302 | /** 303 | * 黄色 - 浅的 304 | */ 305 | public static final int YELLOW_LIGHT = 0xffffffe0; 306 | 307 | /** 308 | * 黄色 - 浅的 - 半透明 309 | */ 310 | public static final int YELLOW_LIGHT_TRANSLUCENT = 0x80ffffe0; 311 | 312 | /** 313 | * 巧克力色 314 | */ 315 | public static final int CHOCOLATE = 0xffd2691e; 316 | 317 | /** 318 | * 巧克力色 - 半透明 319 | */ 320 | public static final int CHOCOLATE_TRANSLUCENT = 0x80d2691e; 321 | 322 | /** 323 | * 番茄色 324 | */ 325 | public static final int TOMATO = 0xffff6347; 326 | 327 | /** 328 | * 番茄色 - 半透明 329 | */ 330 | public static final int TOMATO_TRANSLUCENT = 0x80ff6347; 331 | 332 | /** 333 | * 橙红色 334 | */ 335 | public static final int ORANGERED = 0xffff4500; 336 | 337 | /** 338 | * 橙红色 - 半透明 339 | */ 340 | public static final int ORANGERED_TRANSLUCENT = 0x80ff4500; 341 | 342 | /** 343 | * 银白色 344 | */ 345 | public static final int SILVER = 0xffc0c0c0; 346 | 347 | /** 348 | * 银白色 - 半透明 349 | */ 350 | public static final int SILVER_TRANSLUCENT = 0x80c0c0c0; 351 | 352 | /** 353 | * 高光 354 | */ 355 | public static final int HIGHLIGHT = 0x33ffffff; 356 | 357 | /** 358 | * 低光 359 | */ 360 | public static final int LOWLIGHT = 0x33000000; 361 | } 362 | -------------------------------------------------------------------------------- /app/src/main/java/utils/DateUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Calendar; 6 | import java.util.Date; 7 | 8 | /** 9 | * 日期操作工具类. 10 | * 11 | */ 12 | 13 | public class DateUtil { 14 | 15 | /** 16 | * 英文简写如:2016 17 | */ 18 | public static String FORMAT_Y = "yyyy"; 19 | 20 | /** 21 | * 英文简写如:12:01 22 | */ 23 | public static String FORMAT_HM = "HH:mm"; 24 | 25 | /** 26 | * 英文简写如:1-12 12:01 27 | */ 28 | public static String FORMAT_MDHM = "MM-dd HH:mm"; 29 | 30 | /** 31 | * 英文简写(默认)如:2016-12-01 32 | */ 33 | public static String FORMAT_YMD = "yyyy-MM-dd"; 34 | 35 | /** 36 | * 英文全称 如:2016-12-01 23:15 37 | */ 38 | public static String FORMAT_YMDHM = "yyyy-MM-dd HH:mm"; 39 | 40 | /** 41 | * 英文全称 如:2016-12-01 23:15:06 42 | */ 43 | public static String FORMAT_YMDHMS = "yyyy-MM-dd HH:mm:ss"; 44 | 45 | /** 46 | * 精确到毫秒的完整时间 如:yyyy-MM-dd HH:mm:ss.S 47 | */ 48 | public static String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss.S"; 49 | 50 | /** 51 | * 精确到毫秒的完整时间 如:yyyy-MM-dd HH:mm:ss.S 52 | */ 53 | public static String FORMAT_FULL_SN = "yyyyMMddHHmmssS"; 54 | 55 | /** 56 | * 中文简写 如:2016年12月01日 57 | */ 58 | public static String FORMAT_YMD_CN = "yyyy年MM月dd日"; 59 | 60 | /** 61 | * 中文简写 如:2016年12月01日 12时 62 | */ 63 | public static String FORMAT_YMDH_CN = "yyyy年MM月dd日 HH时"; 64 | 65 | /** 66 | * 中文简写 如:2016年12月01日 12时12分 67 | */ 68 | public static String FORMAT_YMDHM_CN = "yyyy年MM月dd日 HH时mm分"; 69 | 70 | /** 71 | * 中文全称 如:2016年12月01日 23时15分06秒 72 | */ 73 | public static String FORMAT_YMDHMS_CN = "yyyy年MM月dd日 HH时mm分ss秒"; 74 | 75 | /** 76 | * 精确到毫秒的完整中文时间 77 | */ 78 | public static String FORMAT_FULL_CN = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒"; 79 | 80 | public static Calendar calendar = null; 81 | private static final String FORMAT = "yyyy-MM-dd HH:mm:ss"; 82 | 83 | 84 | public static Date str2Date(String str) { 85 | return str2Date(str, null); 86 | } 87 | 88 | 89 | public static Date str2Date(String str, String format) { 90 | if (str == null || str.length() == 0) { 91 | return null; 92 | } 93 | if (format == null || format.length() == 0) { 94 | format = FORMAT; 95 | } 96 | Date date = null; 97 | try { 98 | SimpleDateFormat sdf = new SimpleDateFormat(format); 99 | date = sdf.parse(str); 100 | } catch (Exception e) { 101 | e.printStackTrace(); 102 | } 103 | return date; 104 | } 105 | 106 | 107 | public static Calendar str2Calendar(String str) { 108 | return str2Calendar(str, null); 109 | } 110 | 111 | 112 | public static Calendar str2Calendar(String str, String format) { 113 | 114 | Date date = str2Date(str, format); 115 | if (date == null) { 116 | return null; 117 | } 118 | Calendar c = Calendar.getInstance(); 119 | c.setTime(date); 120 | 121 | return c; 122 | } 123 | 124 | 125 | public static String date2Str(Calendar c) {// yyyy-MM-dd HH:mm:ss 126 | return date2Str(c, null); 127 | } 128 | 129 | 130 | public static String date2Str(Calendar c, String format) { 131 | if (c == null) { 132 | return null; 133 | } 134 | return date2Str(c.getTime(), format); 135 | } 136 | 137 | 138 | public static String date2Str(Date d) {// yyyy-MM-dd HH:mm:ss 139 | return date2Str(d, null); 140 | } 141 | 142 | 143 | public static String date2Str(Date d, String format) {// yyyy-MM-dd HH:mm:ss 144 | if (d == null) { 145 | return null; 146 | } 147 | if (format == null || format.length() == 0) { 148 | format = FORMAT; 149 | } 150 | SimpleDateFormat sdf = new SimpleDateFormat(format); 151 | String s = sdf.format(d); 152 | return s; 153 | } 154 | 155 | 156 | public static String getCurDateStr() { 157 | Calendar c = Calendar.getInstance(); 158 | c.setTime(new Date()); 159 | return c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-" + 160 | c.get(Calendar.DAY_OF_MONTH) + "-" + 161 | c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + 162 | ":" + c.get(Calendar.SECOND); 163 | } 164 | 165 | 166 | /** 167 | * 获得当前日期的字符串格式 168 | * @param format 格式化的类型 169 | * @return 返回格式化之后的事件 170 | */ 171 | public static String getCurDateStr(String format) { 172 | Calendar c = Calendar.getInstance(); 173 | return date2Str(c, format); 174 | 175 | } 176 | 177 | 178 | /** 179 | * 180 | * @param time 当前的时间 181 | * @return 格式到秒 182 | */ 183 | 184 | public static String getMillon(long time) { 185 | 186 | return new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(time); 187 | 188 | } 189 | 190 | 191 | /** 192 | * 193 | * @param time 当前的时间 194 | * @return 当前的天 195 | */ 196 | public static String getDay(long time) { 197 | 198 | return new SimpleDateFormat("yyyy-MM-dd").format(time); 199 | 200 | } 201 | 202 | 203 | /** 204 | * 205 | * @param time 时间 206 | * @return 返回一个毫秒 207 | */ 208 | // 格式到毫秒 209 | public static String getSMillon(long time) { 210 | 211 | return new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS").format(time); 212 | 213 | } 214 | 215 | 216 | /** 217 | * 在日期上增加数个整月 218 | * @param date 日期 219 | * @param n 要增加的月数 220 | * @return 增加数个整月 221 | */ 222 | public static Date addMonth(Date date, int n) { 223 | Calendar cal = Calendar.getInstance(); 224 | cal.setTime(date); 225 | cal.add(Calendar.MONTH, n); 226 | return cal.getTime(); 227 | 228 | } 229 | 230 | 231 | /** 232 | * 在日期上增加天数 233 | * @param date 日期 234 | * @param n 要增加的天数 235 | * @return 增加之后的天数 236 | */ 237 | public static Date addDay(Date date, int n) { 238 | Calendar cal = Calendar.getInstance(); 239 | cal.setTime(date); 240 | cal.add(Calendar.DATE, n); 241 | return cal.getTime(); 242 | 243 | } 244 | 245 | 246 | /** 247 | * 获取距现在某一小时的时刻 248 | * 249 | * @param format 格式化时间的格式 250 | * @param h 距现在的小时 例如:h=-1为上一个小时,h=1为下一个小时 251 | * @return 获取距现在某一小时的时刻 252 | */ 253 | public static String getNextHour(String format, int h) { 254 | SimpleDateFormat sdf = new SimpleDateFormat(format); 255 | Date date = new Date(); 256 | date.setTime(date.getTime() + h * 60 * 60 * 1000); 257 | return sdf.format(date); 258 | 259 | } 260 | 261 | 262 | /** 263 | * 获取时间戳 264 | * @return 获取时间戳 265 | */ 266 | public static String getTimeString() { 267 | SimpleDateFormat df = new SimpleDateFormat(FORMAT_FULL); 268 | Calendar calendar = Calendar.getInstance(); 269 | return df.format(calendar.getTime()); 270 | 271 | } 272 | 273 | 274 | 275 | /** 276 | * 功能描述:返回月 277 | * 278 | * @param date Date 日期 279 | * @return 返回月份 280 | */ 281 | public static int getMonth(Date date) { 282 | calendar = Calendar.getInstance(); 283 | calendar.setTime(date); 284 | return calendar.get(Calendar.MONTH) + 1; 285 | } 286 | 287 | 288 | /** 289 | * 功能描述:返回日 290 | * 291 | * @param date Date 日期 292 | * @return 返回日份 293 | */ 294 | public static int getDay(Date date) { 295 | calendar = Calendar.getInstance(); 296 | calendar.setTime(date); 297 | return calendar.get(Calendar.DAY_OF_MONTH); 298 | } 299 | 300 | 301 | /** 302 | * 功能描述:返回小 303 | * 304 | * @param date 日期 305 | * @return 返回小时 306 | */ 307 | public static int getHour(Date date) { 308 | calendar = Calendar.getInstance(); 309 | calendar.setTime(date); 310 | return calendar.get(Calendar.HOUR_OF_DAY); 311 | } 312 | 313 | 314 | /** 315 | * 功能描述:返回分 316 | * 317 | * @param date 日期 318 | * @return 返回分钟 319 | */ 320 | public static int getMinute(Date date) { 321 | calendar = Calendar.getInstance(); 322 | calendar.setTime(date); 323 | return calendar.get(Calendar.MINUTE); 324 | } 325 | 326 | 327 | /** 328 | * 获得默认的 date pattern 329 | * @return 默认的格式 330 | */ 331 | public static String getDatePattern() { 332 | 333 | return FORMAT_YMDHMS; 334 | } 335 | 336 | 337 | /** 338 | * 返回秒钟 339 | * 340 | * @param date Date 日期 341 | * @return 返回秒钟 342 | */ 343 | public static int getSecond(Date date) { 344 | calendar = Calendar.getInstance(); 345 | 346 | calendar.setTime(date); 347 | return calendar.get(Calendar.SECOND); 348 | } 349 | 350 | 351 | /** 352 | * 使用预设格式提取字符串日期 353 | * 354 | * @param strDate 日期字符串 355 | * @return 提取字符串的日期 356 | */ 357 | public static Date parse(String strDate) { 358 | return parse(strDate, getDatePattern()); 359 | 360 | } 361 | 362 | 363 | /** 364 | * 功能描述:返回毫 365 | * 366 | * @param date 日期 367 | * @return 返回毫 368 | */ 369 | public static long getMillis(Date date) { 370 | calendar = Calendar.getInstance(); 371 | calendar.setTime(date); 372 | return calendar.getTimeInMillis(); 373 | } 374 | 375 | 376 | /** 377 | * 按默认格式的字符串距离今天的天数 378 | * 379 | * @param date 日期字符串 380 | * @return 按默认格式的字符串距离今天的天数 381 | */ 382 | public static int countDays(String date) { 383 | long t = Calendar.getInstance().getTime().getTime(); 384 | Calendar c = Calendar.getInstance(); 385 | c.setTime(parse(date)); 386 | long t1 = c.getTime().getTime(); 387 | return (int) (t / 1000 - t1 / 1000) / 3600 / 24; 388 | 389 | } 390 | 391 | 392 | /** 393 | * 使用用户格式提取字符串日期 394 | * 395 | * @param strDate 日期字符串 396 | * @param pattern 日期格式 397 | * @return 提取字符串日期 398 | */ 399 | public static Date parse(String strDate, String pattern) { 400 | SimpleDateFormat df = new SimpleDateFormat(pattern); 401 | try { 402 | return df.parse(strDate); 403 | } catch (ParseException e) { 404 | e.printStackTrace(); 405 | return null; 406 | } 407 | 408 | } 409 | 410 | 411 | /** 412 | * 按用户格式字符串距离今天的天数 413 | * 414 | * @param date 日期字符串 415 | * @param format 日期格式 416 | * @return 按用户格式字符串距离今天的天数 417 | */ 418 | public static int countDays(String date, String format) { 419 | long t = Calendar.getInstance().getTime().getTime(); 420 | Calendar c = Calendar.getInstance(); 421 | c.setTime(parse(date, format)); 422 | long t1 = c.getTime().getTime(); 423 | return (int) (t / 1000 - t1 / 1000) / 3600 / 24; 424 | } 425 | 426 | } 427 | -------------------------------------------------------------------------------- /app/src/main/java/utils/DensityUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.content.Context; 4 | import android.util.TypedValue; 5 | 6 | /** 7 | * 单位转换类 8 | */ 9 | public class DensityUtil { 10 | 11 | /** 12 | * cannot be instantiated 13 | */ 14 | private DensityUtil() { 15 | throw new UnsupportedOperationException("cannot be instantiated"); 16 | } 17 | 18 | /** 19 | * dp转px 20 | * 21 | * @param context 22 | * @param dpVal 23 | * @return 24 | */ 25 | public static int dp2px(Context context, float dpVal) { 26 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 27 | dpVal, context.getResources().getDisplayMetrics()); 28 | } 29 | 30 | /** 31 | * sp转px 32 | * 33 | * @param context 34 | * @param spVal 35 | * @return 36 | */ 37 | public static int sp2px(Context context, float spVal) { 38 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 39 | spVal, context.getResources().getDisplayMetrics()); 40 | } 41 | 42 | /** 43 | * px转dp 44 | * 45 | * @param context 46 | * @param pxVal 47 | * @return 48 | */ 49 | public static float px2dp(Context context, float pxVal) { 50 | final float scale = context.getResources().getDisplayMetrics().density; 51 | return (pxVal / scale); 52 | } 53 | 54 | /** 55 | * px转sp 56 | * 57 | * @param context 58 | * @param pxVal 59 | * @return 60 | */ 61 | public static float px2sp(Context context, float pxVal) { 62 | return (pxVal / context.getResources().getDisplayMetrics().scaledDensity); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/utils/ExitActivityUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | 4 | import android.app.Activity; 5 | import android.view.KeyEvent; 6 | import android.widget.Toast; 7 | 8 | /** 9 | * detailed information http://hjxandhmr.github.io/2016/06/29/Android-Elegance-ExitActivity/ 10 | */ 11 | public class ExitActivityUtil extends Activity { 12 | 13 | private long exitTime = 0; 14 | 15 | //重写 onKeyDown方法 16 | @Override 17 | public boolean onKeyDown(int keyCode, KeyEvent event) { 18 | if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { 19 | //两秒之内按返回键就会退出 20 | if ((System.currentTimeMillis() - exitTime) > 2000) { 21 | Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show(); 22 | exitTime = System.currentTimeMillis(); 23 | } else { 24 | finish(); 25 | System.exit(0); 26 | } 27 | return true; 28 | } 29 | return super.onKeyDown(keyCode, event); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/utils/FileUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.InputStream; 7 | 8 | /** 9 | * 文件操作工具类 10 | */ 11 | public class FileUtil { 12 | /** 13 | * 在指定的位置创建指定的文件 14 | * 15 | * @param filePath 完整的文件路径 16 | * @param mkdir 是否创建相关的文件夹 17 | * @throws Exception 18 | */ 19 | public static void mkFile(String filePath, boolean mkdir) throws Exception { 20 | File file = new File(filePath); 21 | file.getParentFile().mkdirs(); 22 | file.createNewFile(); 23 | file = null; 24 | } 25 | 26 | /** 27 | * 在指定的位置创建文件夹 28 | * 29 | * @param dirPath 文件夹路径 30 | * @return 若创建成功,则返回True;反之,则返回False 31 | */ 32 | public static boolean mkDir(String dirPath) { 33 | return new File(dirPath).mkdirs(); 34 | } 35 | 36 | /** 37 | * 删除指定的文件 38 | * 39 | * @param filePath 文件路径 40 | * @return 若删除成功,则返回True;反之,则返回False 41 | * 42 | */ 43 | public static boolean delFile(String filePath) { 44 | return new File(filePath).delete(); 45 | } 46 | 47 | /** 48 | * 删除指定的文件夹 49 | * 50 | * @param dirPath 文件夹路径 51 | * @param delFile 文件夹中是否包含文件 52 | * @return 若删除成功,则返回True;反之,则返回False 53 | * 54 | */ 55 | public static boolean delDir(String dirPath, boolean delFile) { 56 | if (delFile) { 57 | File file = new File(dirPath); 58 | if (file.isFile()) { 59 | return file.delete(); 60 | } else if (file.isDirectory()) { 61 | if (file.listFiles().length == 0) { 62 | return file.delete(); 63 | } else { 64 | int zfiles = file.listFiles().length; 65 | File[] delfile = file.listFiles(); 66 | for (int i = 0; i < zfiles; i++) { 67 | if (delfile[i].isDirectory()) { 68 | delDir(delfile[i].getAbsolutePath(), true); 69 | } 70 | delfile[i].delete(); 71 | } 72 | return file.delete(); 73 | } 74 | } else { 75 | return false; 76 | } 77 | } else { 78 | return new File(dirPath).delete(); 79 | } 80 | } 81 | 82 | /** 83 | * 复制文件/文件夹 若要进行文件夹复制,请勿将目标文件夹置于源文件夹中 84 | * @param source 源文件(夹) 85 | * @param target 目标文件(夹) 86 | * @param isFolder 若进行文件夹复制,则为True;反之为False 87 | * @throws Exception 88 | */ 89 | public static void copy(String source, String target, boolean isFolder) 90 | throws Exception { 91 | if (isFolder) { 92 | (new File(target)).mkdirs(); 93 | File a = new File(source); 94 | String[] file = a.list(); 95 | File temp = null; 96 | for (int i = 0; i < file.length; i++) { 97 | if (source.endsWith(File.separator)) { 98 | temp = new File(source + file[i]); 99 | } else { 100 | temp = new File(source + File.separator + file[i]); 101 | } 102 | if (temp.isFile()) { 103 | FileInputStream input = new FileInputStream(temp); 104 | FileOutputStream output = new FileOutputStream(target + "/" + (temp.getName()).toString()); 105 | byte[] b = new byte[1024]; 106 | int len; 107 | while ((len = input.read(b)) != -1) { 108 | output.write(b, 0, len); 109 | } 110 | output.flush(); 111 | output.close(); 112 | input.close(); 113 | }if (temp.isDirectory()) { 114 | copy(source + "/" + file[i], target + "/" + file[i], true); 115 | } 116 | } 117 | } else { 118 | int byteread = 0; 119 | File oldfile = new File(source); 120 | if (oldfile.exists()) { 121 | InputStream inStream = new FileInputStream(source); 122 | File file = new File(target); 123 | file.getParentFile().mkdirs(); 124 | file.createNewFile(); 125 | FileOutputStream fs = new FileOutputStream(file); 126 | byte[] buffer = new byte[1024]; 127 | while ((byteread = inStream.read(buffer)) != -1) { 128 | fs.write(buffer, 0, byteread); 129 | } 130 | inStream.close(); 131 | fs.close(); 132 | } 133 | } 134 | } 135 | 136 | /** 137 | * 移动指定的文件(夹)到目标文件(夹) 138 | * @param source 源文件(夹) 139 | * @param target 目标文件(夹) 140 | * @param isFolder 若为文件夹,则为True;反之为False 141 | * @return 142 | * @throws Exception 143 | */ 144 | public static boolean move(String source, String target, boolean isFolder) 145 | throws Exception { 146 | copy(source, target, isFolder); 147 | if (isFolder) { 148 | return delDir(source, true); 149 | } else { 150 | return delFile(source); 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /app/src/main/java/utils/HttpUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.InputStreamReader; 8 | import java.io.PrintWriter; 9 | import java.net.HttpURLConnection; 10 | import java.net.URL; 11 | 12 | /** 13 | * Http请求的相关工具类 14 | */ 15 | public class HttpUtil { 16 | 17 | private static final int TIMEOUT_IN_MILLIONS = 5000; 18 | 19 | public interface CallBack { 20 | void onRequestComplete(String requst); 21 | } 22 | 23 | /** 24 | * 异步的Get请求 25 | * 26 | * @param urlStr 27 | * @param callBack 28 | */ 29 | public static void doGetAsyn(final String urlStr, final CallBack callBack) { 30 | new Thread(new Runnable() { 31 | @Override 32 | public void run() { 33 | try { 34 | String result = doGet(urlStr); 35 | if (callBack != null) { 36 | callBack.onRequestComplete(result); 37 | } 38 | } catch (Exception e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | }).start(); 43 | } 44 | 45 | /** 46 | * 异步的Post请求 47 | * @param urlStr 48 | * @param params 49 | * @param callBack 50 | * @throws Exception 51 | */ 52 | public static void doPostAsyn(final String urlStr, final String params, 53 | final CallBack callBack) throws Exception { 54 | new Thread(new Runnable() { 55 | @Override 56 | public void run() { 57 | try { 58 | String result = doPost(urlStr, params); 59 | if (callBack != null) { 60 | callBack.onRequestComplete(result); 61 | } 62 | } catch (Exception e) { 63 | e.printStackTrace(); 64 | } 65 | } 66 | }).start(); 67 | } 68 | 69 | 70 | /** 71 | * Get请求,获得返回数据 72 | * 73 | * @param urlStr 74 | * @return 75 | * @throws Exception 76 | */ 77 | public static String doGet(String urlStr) { 78 | URL url = null; 79 | HttpURLConnection conn = null; 80 | InputStream is = null; 81 | ByteArrayOutputStream baos = null; 82 | try { 83 | url = new URL(urlStr); 84 | conn = (HttpURLConnection) url.openConnection(); 85 | conn.setReadTimeout(TIMEOUT_IN_MILLIONS); 86 | conn.setConnectTimeout(TIMEOUT_IN_MILLIONS); 87 | conn.setRequestMethod("GET"); 88 | conn.setRequestProperty("accept", "*/*"); 89 | conn.setRequestProperty("connection", "Keep-Alive"); 90 | if (conn.getResponseCode() == 200) { 91 | is = conn.getInputStream(); 92 | baos = new ByteArrayOutputStream(); 93 | int len = -1; 94 | byte[] buf = new byte[128]; 95 | 96 | while ((len = is.read(buf)) != -1) { 97 | baos.write(buf, 0, len); 98 | } 99 | baos.flush(); 100 | return baos.toString(); 101 | } else { 102 | throw new RuntimeException(" responseCode is not 200 ... "); 103 | } 104 | 105 | } catch (Exception e) { 106 | e.printStackTrace(); 107 | } finally { 108 | try { 109 | if (is != null) 110 | is.close(); 111 | } catch (IOException e) { 112 | e.printStackTrace(); 113 | } 114 | try { 115 | if (baos != null) 116 | baos.close(); 117 | } catch (IOException e) { 118 | e.printStackTrace(); 119 | } 120 | conn.disconnect(); 121 | } 122 | 123 | return null; 124 | } 125 | 126 | /** 127 | * 向指定 URL 发送POST方法的请求 128 | * 129 | * @param url 发送请求的 URL 130 | * @param param 131 | * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 132 | * @return 所代表远程资源的响应结果 133 | * @throws Exception 134 | */ 135 | public static String doPost(String url, String param) { 136 | PrintWriter out = null; 137 | BufferedReader in = null; 138 | String result = ""; 139 | try { 140 | URL realUrl = new URL(url); 141 | // 打开和URL之间的连接 142 | HttpURLConnection conn = (HttpURLConnection) realUrl 143 | .openConnection(); 144 | // 设置通用的请求属性 145 | conn.setRequestProperty("accept", "*/*"); 146 | conn.setRequestProperty("connection", "Keep-Alive"); 147 | conn.setRequestMethod("POST"); 148 | conn.setRequestProperty("Content-Type", 149 | "application/x-www-form-urlencoded"); 150 | conn.setRequestProperty("charset", "utf-8"); 151 | conn.setUseCaches(false); 152 | // 发送POST请求必须设置如下两行 153 | conn.setDoOutput(true); 154 | conn.setDoInput(true); 155 | conn.setReadTimeout(TIMEOUT_IN_MILLIONS); 156 | conn.setConnectTimeout(TIMEOUT_IN_MILLIONS); 157 | if (param != null && !param.trim().equals("")) { 158 | // 获取URLConnection对象对应的输出流 159 | out = new PrintWriter(conn.getOutputStream()); 160 | // 发送请求参数 161 | out.print(param); 162 | // flush输出流的缓冲 163 | out.flush(); 164 | } 165 | // 定义BufferedReader输入流来读取URL的响应 166 | in = new BufferedReader( 167 | new InputStreamReader(conn.getInputStream())); 168 | String line; 169 | while ((line = in.readLine()) != null) { 170 | result += line; 171 | } 172 | } catch (Exception e) { 173 | e.printStackTrace(); 174 | } 175 | // 使用finally块来关闭输出流、输入流 176 | finally { 177 | try { 178 | if (out != null) { 179 | out.close(); 180 | } 181 | if (in != null) { 182 | in.close(); 183 | } 184 | } catch (IOException ex) { 185 | ex.printStackTrace(); 186 | } 187 | } 188 | return result; 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /app/src/main/java/utils/LogUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.util.Log; 4 | 5 | /** 6 | * Log统一管理类 7 | */ 8 | public class LogUtil { 9 | 10 | private LogUtil() { 11 | /* cannot be instantiated */ 12 | throw new UnsupportedOperationException("cannot be instantiated"); 13 | } 14 | 15 | // 是否需要打印bug,可以在application的onCreate函数里面初始化 16 | public static boolean isDebug = true; 17 | private static final String TAG = "LogUtil"; 18 | 19 | // 下面四个是默认tag的函数 20 | public static void i(String msg) 21 | { 22 | if (isDebug) 23 | Log.i(TAG, msg); 24 | } 25 | 26 | public static void d(String msg) 27 | { 28 | if (isDebug) 29 | Log.d(TAG, msg); 30 | } 31 | 32 | public static void e(String msg) 33 | { 34 | if (isDebug) 35 | Log.e(TAG, msg); 36 | } 37 | 38 | public static void v(String msg) 39 | { 40 | if (isDebug) 41 | Log.v(TAG, msg); 42 | } 43 | 44 | // 下面是传入自定义tag的函数 45 | public static void i(String tag, String msg) 46 | { 47 | if (isDebug) 48 | Log.i(tag, msg); 49 | } 50 | 51 | public static void d(String tag, String msg) 52 | { 53 | if (isDebug) 54 | Log.d(tag, msg); 55 | } 56 | 57 | public static void e(String tag, String msg) 58 | { 59 | if (isDebug) 60 | Log.e(tag, msg); 61 | } 62 | 63 | public static void v(String tag, String msg) 64 | { 65 | if (isDebug) 66 | Log.v(tag, msg); 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /app/src/main/java/utils/NetUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.app.Activity; 4 | import android.content.ComponentName; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.net.ConnectivityManager; 8 | import android.net.NetworkInfo; 9 | 10 | /** 11 | * 网络相关辅助类 12 | */ 13 | public class NetUtil { 14 | 15 | private NetUtil() { 16 | /* cannot be instantiated */ 17 | throw new UnsupportedOperationException("cannot be instantiated"); 18 | } 19 | 20 | /** 21 | * 判断网络是否连接 22 | * 23 | * @param context 24 | * @return 25 | */ 26 | public static boolean isConnected(Context context) { 27 | ConnectivityManager connectivityManager = (ConnectivityManager) context 28 | .getSystemService(Context.CONNECTIVITY_SERVICE); 29 | if (null != connectivityManager) { 30 | NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 31 | if (networkInfo != null && networkInfo.isConnected()) { 32 | if (networkInfo.getState() == NetworkInfo.State.CONNECTING) { 33 | return true; 34 | } 35 | } 36 | } 37 | return false; 38 | } 39 | 40 | /** 41 | * 判断是否是WIFI连接 42 | * 43 | * @param context 44 | * @return 45 | */ 46 | public static boolean isWIFI(Context context) { 47 | 48 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 49 | if (connectivityManager == null) 50 | return false; 51 | return connectivityManager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI; 52 | } 53 | 54 | /** 55 | * 打开网络设置界面 56 | */ 57 | public static void openSetting(Activity activity) { 58 | Intent intent = new Intent("/"); 59 | ComponentName cm = new ComponentName("com.android.settings", 60 | "com.android.settings.WirelessSettings"); 61 | intent.setComponent(cm); 62 | intent.setAction("android.intent.action.VIEW"); 63 | activity.startActivityForResult(intent, 0); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/utils/PhoneUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.net.Uri; 7 | import android.provider.MediaStore; 8 | import java.io.File; 9 | 10 | /** 11 | * 手机组件调用工具类 12 | * 13 | * @author 14 | */ 15 | public final class PhoneUtil { 16 | private static long lastClickTime; 17 | /** 18 | * Don't let anyone instantiate this class. 19 | */ 20 | private PhoneUtil() { 21 | throw new Error("Do not need instantiate!"); 22 | } 23 | 24 | 25 | /** 26 | * 调用系统发短信界面 27 | * 28 | * @param activity Activity 29 | * @param phoneNumber 手机号码 30 | * @param smsContent 短信内容 31 | */ 32 | public static void sendMessage(Context activity, String phoneNumber, String smsContent) { 33 | if (phoneNumber == null || phoneNumber.length() < 4) { 34 | return; 35 | } 36 | Uri uri = Uri.parse("smsto:" + phoneNumber); 37 | Intent it = new Intent(Intent.ACTION_SENDTO, uri); 38 | it.putExtra("sms_body", smsContent); 39 | it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 40 | activity.startActivity(it); 41 | } 42 | 43 | 44 | /** 45 | * 判断是否为连击 46 | * 47 | * @return boolean 48 | */ 49 | public static boolean isFastDoubleClick() { 50 | long time = System.currentTimeMillis(); 51 | long timeD = time - lastClickTime; 52 | if (0 < timeD && timeD < 500) { 53 | return true; 54 | } 55 | lastClickTime = time; 56 | return false; 57 | } 58 | 59 | /** 60 | * 获取手机型号 61 | * 62 | * @param context 上下文 63 | * @return String 64 | */ 65 | public static String getMobileModel(Context context) { 66 | try { 67 | // 手机型号 68 | String model = android.os.Build.MODEL; 69 | return model; 70 | } catch (Exception e) { 71 | return "未知"; 72 | } 73 | } 74 | 75 | /** 76 | * 获取手机品牌 77 | * 78 | * @param context 上下文 79 | * @return String 80 | */ 81 | public static String getMobileBrand(Context context) { 82 | try { 83 | // android系统版本号 84 | String brand = android.os.Build.BRAND; 85 | return brand; 86 | } catch (Exception e) { 87 | return "未知"; 88 | } 89 | } 90 | 91 | 92 | /** 93 | *拍照打开照相机! 94 | * @param requestcode 返回值 95 | * @param activity 上下文 96 | * @param fileName 生成的图片文件的路径 97 | */ 98 | public static void toTakePhoto(int requestcode, Activity activity,String fileName) { 99 | Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 100 | intent.putExtra("camerasensortype", 2);// 调用前置摄像头 101 | intent.putExtra("autofocus", true);// 自动对焦 102 | intent.putExtra("fullScreen", false);// 全屏 103 | intent.putExtra("showActionIcons", false); 104 | try {//创建一个当前任务id的文件然后里面存放任务的照片的和路径!这主文件的名字是用uuid到时候在用任务id去查路径! 105 | File file = new File(fileName); 106 | if(!file.exists()){//如果这个文件不存在就创建一个文件夹! 107 | file.mkdirs(); 108 | } 109 | Uri uri = Uri.fromFile(new File(fileName)); 110 | intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 111 | activity.startActivityForResult(intent, requestcode); 112 | } catch (Exception e) { 113 | e.printStackTrace(); 114 | } 115 | } 116 | 117 | 118 | /** 119 | *打开相册 120 | * @param requestcode 响应码 121 | * @param activity 上下文 122 | */ 123 | public static void toTakePicture(int requestcode, Activity activity){ 124 | Intent intent = new Intent(Intent.ACTION_PICK, null); 125 | intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 126 | "image/*"); 127 | activity.startActivityForResult(intent, requestcode); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/java/utils/SDCardUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.os.Environment; 4 | import android.os.StatFs; 5 | 6 | import java.io.File; 7 | 8 | /** 9 | * SD卡辅助类 10 | */ 11 | public class SDCardUtil { 12 | 13 | private SDCardUtil() { 14 | /* cannot be instantiated */ 15 | throw new UnsupportedOperationException("cannot be instantiated"); 16 | } 17 | 18 | /** 19 | * 判断SDCard是否可用 20 | * 21 | * @return 22 | */ 23 | public static boolean isSDCardEnable() { 24 | return Environment.getExternalStorageState().equals( 25 | Environment.MEDIA_MOUNTED); 26 | 27 | } 28 | 29 | /** 30 | * 获取SD卡路径 31 | * 32 | * @return 33 | */ 34 | public static String getSDCardPath() { 35 | return Environment.getExternalStorageDirectory().getAbsolutePath() 36 | + File.separator; 37 | } 38 | 39 | /** 40 | * 获取SD卡的剩余容量 单位byte 41 | * 42 | * @return 43 | */ 44 | public static long getSDCardAllSize() { 45 | if (isSDCardEnable()) { 46 | StatFs stat = new StatFs(getSDCardPath()); 47 | // 获取空闲的数据块的数量 48 | long availableBlocks = (long) stat.getAvailableBlocks() - 4; 49 | // 获取单个数据块的大小(byte) 50 | long freeBlocks = stat.getAvailableBlocks(); 51 | return freeBlocks * availableBlocks; 52 | } 53 | return 0; 54 | } 55 | 56 | /** 57 | * 获取指定路径所在空间的剩余可用容量字节数,单位byte 58 | * 59 | * @param filePath 60 | * @return 容量字节 SDCard可用空间,内部存储可用空间 61 | */ 62 | public static long getFreeBytes(String filePath) 63 | { 64 | // 如果是sd卡的下的路径,则获取sd卡可用容量 65 | if (filePath.startsWith(getSDCardPath())) { 66 | filePath = getSDCardPath(); 67 | } else { 68 | // 如果是内部存储的路径,则获取内存存储的可用容量 69 | filePath = Environment.getDataDirectory().getAbsolutePath(); 70 | } 71 | StatFs stat = new StatFs(filePath); 72 | long availableBlocks = (long) stat.getAvailableBlocks() - 4; 73 | return stat.getBlockSize() * availableBlocks; 74 | } 75 | 76 | /** 77 | * 获取系统存储路径 78 | * 79 | * @return 80 | */ 81 | public static String getRootDirectoryPath() { 82 | return Environment.getRootDirectory().getAbsolutePath(); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/utils/SPUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | import java.util.Map; 9 | 10 | /** 11 | * SharedPreferences统一管理类 12 | */ 13 | public class SPUtil { 14 | /** 15 | * 保存在手机里面的文件名 16 | */ 17 | public static final String FILE_NAME = "share_data"; 18 | 19 | /** 20 | * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法 21 | * 22 | * @param context 23 | * @param key 24 | * @param object 25 | */ 26 | public static void put(Context context, String key, Object object) { 27 | 28 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 29 | Context.MODE_PRIVATE); 30 | SharedPreferences.Editor editor = sp.edit(); 31 | 32 | if (object instanceof String) { 33 | editor.putString(key, (String) object); 34 | } else if (object instanceof Integer) { 35 | editor.putInt(key, (Integer) object); 36 | } else if (object instanceof Boolean) { 37 | editor.putBoolean(key, (Boolean) object); 38 | } else if (object instanceof Float) { 39 | editor.putFloat(key, (Float) object); 40 | } else if (object instanceof Long) { 41 | editor.putLong(key, (Long) object); 42 | } else { 43 | editor.putString(key, object.toString()); 44 | } 45 | SharedPreferencesCompat.apply(editor); 46 | } 47 | 48 | 49 | /** 50 | * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值 51 | * 52 | * @param context 53 | * @param key 54 | * @param defaultObject 55 | * @return 56 | */ 57 | public static Object get(Context context, String key, Object defaultObject) 58 | { 59 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 60 | Context.MODE_PRIVATE); 61 | 62 | if (defaultObject instanceof String) { 63 | return sp.getString(key, (String) defaultObject); 64 | } else if (defaultObject instanceof Integer) { 65 | return sp.getInt(key, (Integer) defaultObject); 66 | } else if (defaultObject instanceof Boolean) { 67 | return sp.getBoolean(key, (Boolean) defaultObject); 68 | } else if (defaultObject instanceof Float) { 69 | return sp.getFloat(key, (Float) defaultObject); 70 | } else if (defaultObject instanceof Long) { 71 | return sp.getLong(key, (Long) defaultObject); 72 | } 73 | return null; 74 | } 75 | 76 | /** 77 | * 移除某个key值已经对应的值 78 | * @param context 79 | * @param key 80 | */ 81 | public static void remove(Context context, String key) { 82 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 83 | Context.MODE_PRIVATE); 84 | SharedPreferences.Editor editor = sp.edit(); 85 | editor.remove(key); 86 | SharedPreferencesCompat.apply(editor); 87 | } 88 | 89 | /** 90 | * 清除所有数据 91 | * @param context 92 | */ 93 | public static void clear(Context context) { 94 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 95 | Context.MODE_PRIVATE); 96 | SharedPreferences.Editor editor = sp.edit(); 97 | editor.clear(); 98 | SharedPreferencesCompat.apply(editor); 99 | } 100 | 101 | /** 102 | * 查询某个key是否已经存在 103 | * @param context 104 | * @param key 105 | * @return 106 | */ 107 | public static boolean contains(Context context, String key) { 108 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 109 | Context.MODE_PRIVATE); 110 | return sp.contains(key); 111 | } 112 | 113 | /** 114 | * 返回所有的键值对 115 | * 116 | * @param context 117 | * @return 118 | */ 119 | public static Map getAll(Context context) { 120 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 121 | Context.MODE_PRIVATE); 122 | return sp.getAll(); 123 | } 124 | 125 | /** 126 | * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类 127 | * 128 | * @author zhy 129 | * 130 | */ 131 | private static class SharedPreferencesCompat { 132 | private static final Method sApplyMethod = findApplyMethod(); 133 | 134 | /** 135 | * 反射查找apply的方法 136 | * 137 | * @return 138 | */ 139 | @SuppressWarnings({ "unchecked", "rawtypes" }) 140 | private static Method findApplyMethod() { 141 | try { 142 | Class clz = SharedPreferences.Editor.class; 143 | return clz.getMethod("apply"); 144 | } catch (NoSuchMethodException e) { 145 | } 146 | return null; 147 | } 148 | 149 | /** 150 | * 如果找到则使用apply执行,否则使用commit 151 | * 152 | * @param editor 153 | */ 154 | public static void apply(SharedPreferences.Editor editor) { 155 | try { 156 | if (sApplyMethod != null) { 157 | sApplyMethod.invoke(editor); 158 | return; 159 | } 160 | } catch (IllegalArgumentException e) { 161 | } catch (IllegalAccessException e) { 162 | } catch (InvocationTargetException e) { 163 | } 164 | editor.commit(); 165 | } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /app/src/main/java/utils/ScreenUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Bitmap; 6 | import android.graphics.Rect; 7 | import android.util.DisplayMetrics; 8 | import android.view.View; 9 | import android.view.WindowManager; 10 | 11 | /** 12 | * 屏幕相关辅助类 13 | */ 14 | public class ScreenUtil { 15 | 16 | private ScreenUtil(){ 17 | /*cannot be instantiated*/ 18 | throw new UnsupportedOperationException("cannot be instantiated"); 19 | } 20 | 21 | /** 22 | * 获得屏幕宽度 23 | * 24 | * @param context 25 | * @return 26 | */ 27 | public static int getScreenWidth(Context context) { 28 | WindowManager wm = (WindowManager) context 29 | .getSystemService(Context.WINDOW_SERVICE); 30 | DisplayMetrics outMetrics = new DisplayMetrics(); 31 | wm.getDefaultDisplay().getMetrics(outMetrics); 32 | return outMetrics.widthPixels; 33 | } 34 | 35 | /** 36 | * 获得屏幕高度 37 | * 38 | * @param context 39 | * @return 40 | */ 41 | public static int getScreenHeight(Context context) { 42 | WindowManager wm = (WindowManager) context 43 | .getSystemService(Context.WINDOW_SERVICE); 44 | DisplayMetrics outMetrics = new DisplayMetrics(); 45 | wm.getDefaultDisplay().getMetrics(outMetrics); 46 | return outMetrics.heightPixels; 47 | } 48 | 49 | /** 50 | * 获得状态栏的高度 51 | * 52 | * @param context 53 | * @return 54 | */ 55 | public static int getStatusHeight(Context context) { 56 | 57 | int statusHeight = -1; 58 | try { 59 | Class clazz = Class.forName("com.android.internal.R$dimen"); 60 | Object object = clazz.newInstance(); 61 | int height = Integer.parseInt(clazz.getField("status_bar_height") 62 | .get(object).toString()); 63 | statusHeight = context.getResources().getDimensionPixelSize(height); 64 | } catch (Exception e) { 65 | e.printStackTrace(); 66 | } 67 | return statusHeight; 68 | } 69 | 70 | /** 71 | * 获取当前屏幕截图,包含状态栏 72 | * 73 | * @param activity 74 | * @return 75 | */ 76 | public static Bitmap snapShotWithStatusBar(Activity activity) { 77 | View view = activity.getWindow().getDecorView(); 78 | view.setDrawingCacheEnabled(true); 79 | view.buildDrawingCache(); 80 | Bitmap bmp = view.getDrawingCache(); 81 | int width = getScreenWidth(activity); 82 | int height = getScreenHeight(activity); 83 | Bitmap bp = null; 84 | bp = Bitmap.createBitmap(bmp, 0, 0, width, height); 85 | view.destroyDrawingCache(); 86 | return bp; 87 | } 88 | 89 | /** 90 | * 获取当前屏幕截图,不包含状态栏 91 | * 92 | * @param activity 93 | * @return 94 | */ 95 | public static Bitmap snapShotWithoutStatusBar(Activity activity) { 96 | View view = activity.getWindow().getDecorView(); 97 | view.setDrawingCacheEnabled(true); 98 | view.buildDrawingCache(); 99 | Bitmap bmp = view.getDrawingCache(); 100 | Rect frame = new Rect(); 101 | activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); 102 | int statusBarHeight = frame.top; 103 | 104 | int width = getScreenWidth(activity); 105 | int height = getScreenHeight(activity); 106 | Bitmap bp = null; 107 | bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height 108 | - statusBarHeight); 109 | view.destroyDrawingCache(); 110 | return bp; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/utils/ShortCutUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.app.Activity; 4 | import android.content.ComponentName; 5 | import android.content.ContentResolver; 6 | import android.content.Intent; 7 | import android.database.Cursor; 8 | import android.net.Uri; 9 | 10 | import com.example.hjx.androidutils.R; 11 | 12 | /** 13 | * 创建删除快捷图标 14 | * 15 | * 需要权限: com.android.launcher.permission.INSTALL_SHORTCUT 16 | * com.android.launcher.permission.UNINSTALL_SHORTCUT 17 | */ 18 | public final class ShortCutUtil { 19 | 20 | /** 21 | * Don't let anyone instantiate this class. 22 | */ 23 | private ShortCutUtil() { 24 | throw new Error("Do not need instantiate!"); 25 | } 26 | 27 | /** 28 | * 检测是否存在快捷键 29 | * 30 | * @param activity Activity 31 | * @return 是否存在桌面图标 32 | */ 33 | public static boolean hasShortcut(Activity activity) { 34 | boolean isInstallShortcut = false; 35 | final ContentResolver cr = activity.getContentResolver(); 36 | final String AUTHORITY = "com.android.launcher.settings"; 37 | final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY 38 | + "/favorites?notify=true"); 39 | Cursor c = cr.query(CONTENT_URI, 40 | new String[]{"title", "iconResource"}, "title=?", 41 | new String[]{activity.getString(R.string.app_name).trim()}, 42 | null); 43 | if (c != null && c.getCount() > 0) { 44 | isInstallShortcut = true; 45 | } 46 | return isInstallShortcut; 47 | } 48 | 49 | /** 50 | * 为程序创建桌面快捷方式 51 | * 52 | * @param activity Activity 53 | * @param res res 54 | */ 55 | public static void addShortcut(Activity activity,int res) { 56 | 57 | Intent shortcut = new Intent( 58 | "com.android.launcher.action.INSTALL_SHORTCUT"); 59 | // 快捷方式的名称 60 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, 61 | activity.getString(R.string.app_name)); 62 | // 不允许重复创建 63 | shortcut.putExtra("duplicate", false); 64 | Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); 65 | shortcutIntent.setClassName(activity, activity.getClass().getName()); 66 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); 67 | // 快捷方式的图标 68 | Intent.ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext( 69 | activity, res); 70 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes); 71 | 72 | activity.sendBroadcast(shortcut); 73 | } 74 | 75 | /** 76 | * 删除程序的快捷方式 77 | * 78 | * @param activity Activity 79 | */ 80 | public static void delShortcut(Activity activity) { 81 | 82 | Intent shortcut = new Intent( 83 | "com.android.launcher.action.UNINSTALL_SHORTCUT"); 84 | // 快捷方式的名称 85 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, 86 | activity.getString(R.string.app_name)); 87 | String appClass = activity.getPackageName() + "." 88 | + activity.getLocalClassName(); 89 | ComponentName comp = new ComponentName(activity.getPackageName(), 90 | appClass); 91 | shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent( 92 | Intent.ACTION_MAIN).setComponent(comp)); 93 | activity.sendBroadcast(shortcut); 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /app/src/main/java/utils/StringUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | import java.security.MessageDigest; 6 | import java.util.ArrayList; 7 | import java.util.Locale; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | /** 12 | * 字符串工具类,提供一些字符串相关的便捷方法 13 | */ 14 | public class StringUtil { 15 | 16 | private StringUtil() { 17 | throw new AssertionError(); 18 | } 19 | 20 | 21 | /** 22 | * is null or its length is 0 or it is made by space 23 | * 24 | *
 25 |      * isBlank(null) = true;
 26 |      * isBlank("") = true;
 27 |      * isBlank("  ") = true;
 28 |      * isBlank("a") = false;
 29 |      * isBlank("a ") = false;
 30 |      * isBlank(" a") = false;
 31 |      * isBlank("a b") = false;
 32 |      * 
33 | * 34 | * @param str str 35 | * @return if string is null or its size is 0 or it is made by space, return 36 | * true, else return false. 37 | */ 38 | public static boolean isBlank(String str) { 39 | 40 | return (str == null || str.trim().length() == 0); 41 | } 42 | 43 | 44 | /** 45 | * is null or its length is 0 46 | * 47 | *
 48 |      * isEmpty(null) = true;
 49 |      * isEmpty("") = true;
 50 |      * isEmpty("  ") = false;
 51 |      * 
52 | * 53 | * @param str str 54 | * @return if string is null or its size is 0, return true, else return 55 | * false. 56 | */ 57 | public static boolean isEmpty(CharSequence str) { 58 | 59 | return (str == null || str.length() == 0); 60 | } 61 | 62 | 63 | /** 64 | * get length of CharSequence 65 | * 66 | *
 67 |      * length(null) = 0;
 68 |      * length(\"\") = 0;
 69 |      * length(\"abc\") = 3;
 70 |      * 
71 | * 72 | * @param str str 73 | * @return if str is null or empty, return 0, else return {@link 74 | * CharSequence#length()}. 75 | */ 76 | public static int length(CharSequence str) { 77 | 78 | return str == null ? 0 : str.length(); 79 | } 80 | 81 | 82 | /** 83 | * null Object to empty string 84 | * 85 | *
 86 |      * nullStrToEmpty(null) = "";
 87 |      * nullStrToEmpty("") = "";
 88 |      * nullStrToEmpty("aa") = "aa";
 89 |      * 
90 | * 91 | * @param str str 92 | * @return String 93 | */ 94 | public static String nullStrToEmpty(Object str) { 95 | 96 | return (str == null 97 | ? "" 98 | : (str instanceof String ? (String) str : str.toString())); 99 | } 100 | 101 | 102 | /** 103 | * @param str str 104 | * @return String 105 | */ 106 | public static String capitalizeFirstLetter(String str) { 107 | 108 | if (isEmpty(str)) { 109 | return str; 110 | } 111 | 112 | char c = str.charAt(0); 113 | return (!Character.isLetter(c) || Character.isUpperCase(c)) 114 | ? str 115 | : new StringBuilder(str.length()).append( 116 | Character.toUpperCase(c)) 117 | .append(str.substring(1)) 118 | .toString(); 119 | } 120 | 121 | 122 | /** 123 | * encoded in utf-8 124 | * 125 | * @param str 字符串 126 | * @return 返回一个utf8的字符串 127 | */ 128 | public static String utf8Encode(String str) { 129 | 130 | if (!isEmpty(str) && str.getBytes().length != str.length()) { 131 | try { 132 | return URLEncoder.encode(str, "UTF-8"); 133 | } catch (UnsupportedEncodingException e) { 134 | throw new RuntimeException( 135 | "UnsupportedEncodingException occurred. ", e); 136 | } 137 | } 138 | return str; 139 | } 140 | 141 | 142 | /** 143 | * @param href 字符串 144 | * @return 返回一个html 145 | */ 146 | public static String getHrefInnerHtml(String href) { 147 | 148 | if (isEmpty(href)) { 149 | return ""; 150 | } 151 | 152 | String hrefReg = ".*<[\\s]*a[\\s]*.*>(.+?)<[\\s]*/a[\\s]*>.*"; 153 | Pattern hrefPattern = Pattern.compile(hrefReg, 154 | Pattern.CASE_INSENSITIVE); 155 | Matcher hrefMatcher = hrefPattern.matcher(href); 156 | if (hrefMatcher.matches()) { 157 | return hrefMatcher.group(1); 158 | } 159 | return href; 160 | } 161 | 162 | 163 | /** 164 | * @param source 字符串 165 | * @return 返回htmL到字符串 166 | */ 167 | public static String htmlEscapeCharsToString(String source) { 168 | 169 | return StringUtil.isEmpty(source) 170 | ? source 171 | : source.replaceAll("<", "<") 172 | .replaceAll(">", ">") 173 | .replaceAll("&", "&") 174 | .replaceAll(""", "\""); 175 | } 176 | 177 | 178 | /** 179 | * @param s str 180 | * @return String 181 | */ 182 | public static String fullWidthToHalfWidth(String s) { 183 | 184 | if (isEmpty(s)) { 185 | return s; 186 | } 187 | 188 | char[] source = s.toCharArray(); 189 | for (int i = 0; i < source.length; i++) { 190 | if (source[i] == 12288) { 191 | source[i] = ' '; 192 | // } else if (source[i] == 12290) { 193 | // source[i] = '.'; 194 | } 195 | else if (source[i] >= 65281 && source[i] <= 65374) { 196 | source[i] = (char) (source[i] - 65248); 197 | } 198 | else { 199 | source[i] = source[i]; 200 | } 201 | } 202 | return new String(source); 203 | } 204 | 205 | 206 | /** 207 | * @param s 字符串 208 | * @return 返回的数值 209 | */ 210 | public static String halfWidthToFullWidth(String s) { 211 | 212 | if (isEmpty(s)) { 213 | return s; 214 | } 215 | 216 | char[] source = s.toCharArray(); 217 | for (int i = 0; i < source.length; i++) { 218 | if (source[i] == ' ') { 219 | source[i] = (char) 12288; 220 | // } else if (source[i] == '.') { 221 | // source[i] = (char)12290; 222 | } 223 | else if (source[i] >= 33 && source[i] <= 126) { 224 | source[i] = (char) (source[i] + 65248); 225 | } 226 | else { 227 | source[i] = source[i]; 228 | } 229 | } 230 | return new String(source); 231 | } 232 | 233 | 234 | /** 235 | * @param str 资源 236 | * @return 特殊字符串切换 237 | */ 238 | 239 | public static String replaceBlanktihuan(String str) { 240 | 241 | String dest = ""; 242 | if (str != null) { 243 | Pattern p = Pattern.compile("\\s*|\t|\r|\n"); 244 | Matcher m = p.matcher(str); 245 | dest = m.replaceAll(""); 246 | } 247 | return dest; 248 | } 249 | 250 | 251 | /** 252 | * 判断给定的字符串是否为null或者是空的 253 | * 254 | * @param string 给定的字符串 255 | */ 256 | public static boolean isEmpty(String string) { 257 | return string == null || "".equals(string.trim()); 258 | } 259 | 260 | 261 | /** 262 | * 判断给定的字符串是否不为null且不为空 263 | * 264 | * @param string 给定的字符串 265 | */ 266 | public static boolean isNotEmpty(String string) { 267 | return !isEmpty(string); 268 | } 269 | 270 | 271 | /** 272 | * 判断给定的字符串数组中的所有字符串是否都为null或者是空的 273 | * 274 | * @param strings 给定的字符串 275 | */ 276 | public static boolean isEmpty(String... strings) { 277 | boolean result = true; 278 | for (String string : strings) { 279 | if (isNotEmpty(string)) { 280 | result = false; 281 | break; 282 | } 283 | } 284 | return result; 285 | } 286 | 287 | 288 | /** 289 | * 判断给定的字符串数组中是否全部都不为null且不为空 290 | * 291 | * @param strings 给定的字符串数组 292 | * @return 是否全部都不为null且不为空 293 | */ 294 | public static boolean isNotEmpty(String... strings) { 295 | boolean result = true; 296 | for (String string : strings) { 297 | if (isEmpty(string)) { 298 | result = false; 299 | break; 300 | } 301 | } 302 | return result; 303 | } 304 | 305 | 306 | /** 307 | * 如果字符串是null或者空就返回"" 308 | */ 309 | public static String filterEmpty(String string) { 310 | return StringUtil.isNotEmpty(string) ? string : ""; 311 | } 312 | 313 | 314 | /** 315 | * 在给定的字符串中,用新的字符替换所有旧的字符 316 | * 317 | * @param string 给定的字符串 318 | * @param oldchar 旧的字符 319 | * @param newchar 新的字符 320 | * @return 替换后的字符串 321 | */ 322 | public static String replace(String string, char oldchar, char newchar) { 323 | char chars[] = string.toCharArray(); 324 | for (int w = 0; w < chars.length; w++) { 325 | if (chars[w] == oldchar) { 326 | chars[w] = newchar; 327 | break; 328 | } 329 | } 330 | return new String(chars); 331 | } 332 | 333 | 334 | /** 335 | * 把给定的字符串用给定的字符分割 336 | * 337 | * @param string 给定的字符串 338 | * @param ch 给定的字符 339 | * @return 分割后的字符串数组 340 | */ 341 | public static String[] split(String string, char ch) { 342 | ArrayList stringList = new ArrayList(); 343 | char chars[] = string.toCharArray(); 344 | int nextStart = 0; 345 | for (int w = 0; w < chars.length; w++) { 346 | if (ch == chars[w]) { 347 | stringList.add(new String(chars, nextStart, w - nextStart)); 348 | nextStart = w + 1; 349 | if (nextStart == 350 | chars.length) { //当最后一位是分割符的话,就再添加一个空的字符串到分割数组中去 351 | stringList.add(""); 352 | } 353 | } 354 | } 355 | if (nextStart < 356 | chars.length) { //如果最后一位不是分隔符的话,就将最后一个分割符到最后一个字符中间的左右字符串作为一个字符串添加到分割数组中去 357 | stringList.add(new String(chars, nextStart, 358 | chars.length - 1 - nextStart + 1)); 359 | } 360 | return stringList.toArray(new String[stringList.size()]); 361 | } 362 | 363 | 364 | /** 365 | * 计算给定的字符串的长度,计算规则是:一个汉字的长度为2,一个字符的长度为1 366 | * 367 | * @param string 给定的字符串 368 | * @return 长度 369 | */ 370 | public static int countLength(String string) { 371 | int length = 0; 372 | char[] chars = string.toCharArray(); 373 | for (int w = 0; w < string.length(); w++) { 374 | char ch = chars[w]; 375 | if (ch >= '\u0391' && ch <= '\uFFE5') { 376 | length++; 377 | length++; 378 | } 379 | else { 380 | length++; 381 | } 382 | } 383 | return length; 384 | } 385 | 386 | 387 | private static char[] getChars(char[] chars, int startIndex) { 388 | int endIndex = startIndex + 1; 389 | //如果第一个是数字 390 | if (Character.isDigit(chars[startIndex])) { 391 | //如果下一个是数字 392 | while (endIndex < chars.length && 393 | Character.isDigit(chars[endIndex])) { 394 | endIndex++; 395 | } 396 | } 397 | char[] resultChars = new char[endIndex - startIndex]; 398 | System.arraycopy(chars, startIndex, resultChars, 0, resultChars.length); 399 | return resultChars; 400 | } 401 | 402 | 403 | /** 404 | * 是否全是数字 405 | */ 406 | public static boolean isAllDigital(char[] chars) { 407 | boolean result = true; 408 | for (int w = 0; w < chars.length; w++) { 409 | if (!Character.isDigit(chars[w])) { 410 | result = false; 411 | break; 412 | } 413 | } 414 | return result; 415 | } 416 | 417 | 418 | 419 | 420 | /** 421 | * 删除给定字符串中所有的旧的字符 422 | * 423 | * @param string 源字符串 424 | * @param ch 要删除的字符 425 | * @return 删除后的字符串 426 | */ 427 | public static String removeChar(String string, char ch) { 428 | StringBuffer sb = new StringBuffer(); 429 | for (char cha : string.toCharArray()) { 430 | if (cha != '-') { 431 | sb.append(cha); 432 | } 433 | } 434 | return sb.toString(); 435 | } 436 | 437 | 438 | /** 439 | * 删除给定字符串中给定位置处的字符 440 | * 441 | * @param string 给定字符串 442 | * @param index 给定位置 443 | */ 444 | public static String removeChar(String string, int index) { 445 | String result = null; 446 | char[] chars = string.toCharArray(); 447 | if (index == 0) { 448 | result = new String(chars, 1, chars.length - 1); 449 | } 450 | else if (index == chars.length - 1) { 451 | result = new String(chars, 0, chars.length - 1); 452 | } 453 | else { 454 | result = new String(chars, 0, index) + 455 | new String(chars, index + 1, chars.length - index); 456 | ; 457 | } 458 | return result; 459 | } 460 | 461 | 462 | /** 463 | * 删除给定字符串中给定位置处的字符 464 | * 465 | * @param string 给定字符串 466 | * @param index 给定位置 467 | * @param ch 如果同给定位置处的字符相同,则将给定位置处的字符删除 468 | */ 469 | public static String removeChar(String string, int index, char ch) { 470 | String result = null; 471 | char[] chars = string.toCharArray(); 472 | if (chars.length > 0 && chars[index] == ch) { 473 | if (index == 0) { 474 | result = new String(chars, 1, chars.length - 1); 475 | } 476 | else if (index == chars.length - 1) { 477 | result = new String(chars, 0, chars.length - 1); 478 | } 479 | else { 480 | result = new String(chars, 0, index) + 481 | new String(chars, index + 1, chars.length - index); 482 | ; 483 | } 484 | } 485 | else { 486 | result = string; 487 | } 488 | return result; 489 | } 490 | 491 | 492 | /** 493 | * 对给定的字符串进行空白过滤 494 | * 495 | * @param string 给定的字符串 496 | * @return 如果给定的字符串是一个空白字符串,那么返回null;否则返回本身。 497 | */ 498 | public static String filterBlank(String string) { 499 | if ("".equals(string)) { 500 | return null; 501 | } 502 | else { 503 | return string; 504 | } 505 | } 506 | 507 | 508 | /** 509 | * 将给定字符串中给定的区域的字符转换成小写 510 | * 511 | * @param str 给定字符串中 512 | * @param beginIndex 开始索引(包括) 513 | * @param endIndex 结束索引(不包括) 514 | * @return 新的字符串 515 | */ 516 | public static String toLowerCase(String str, int beginIndex, int endIndex) { 517 | return str.replaceFirst(str.substring(beginIndex, endIndex), 518 | str.substring(beginIndex, endIndex) 519 | .toLowerCase(Locale.getDefault())); 520 | } 521 | 522 | 523 | /** 524 | * 将给定字符串中给定的区域的字符转换成大写 525 | * 526 | * @param str 给定字符串中 527 | * @param beginIndex 开始索引(包括) 528 | * @param endIndex 结束索引(不包括) 529 | * @return 新的字符串 530 | */ 531 | public static String toUpperCase(String str, int beginIndex, int endIndex) { 532 | return str.replaceFirst(str.substring(beginIndex, endIndex), 533 | str.substring(beginIndex, endIndex) 534 | .toUpperCase(Locale.getDefault())); 535 | } 536 | 537 | 538 | /** 539 | * 将给定字符串的首字母转为小写 540 | * 541 | * @param str 给定字符串 542 | * @return 新的字符串 543 | */ 544 | public static String firstLetterToLowerCase(String str) { 545 | return toLowerCase(str, 0, 1); 546 | } 547 | 548 | 549 | /** 550 | * 将给定字符串的首字母转为大写 551 | * 552 | * @param str 给定字符串 553 | * @return 新的字符串 554 | */ 555 | public static String firstLetterToUpperCase(String str) { 556 | return toUpperCase(str, 0, 1); 557 | } 558 | 559 | 560 | /** 561 | * 将给定的字符串MD5加密 562 | * 563 | * @param string 给定的字符串 564 | * @return MD5加密后生成的字符串 565 | */ 566 | public static String MD5(String string) { 567 | String result = null; 568 | try { 569 | char[] charArray = string.toCharArray(); 570 | byte[] byteArray = new byte[charArray.length]; 571 | for (int i = 0; i < charArray.length; i++) { 572 | byteArray[i] = (byte) charArray[i]; 573 | } 574 | 575 | StringBuffer hexValue = new StringBuffer(); 576 | byte[] md5Bytes = MessageDigest.getInstance("MD5") 577 | .digest(byteArray); 578 | for (int i = 0; i < md5Bytes.length; i++) { 579 | int val = ((int) md5Bytes[i]) & 0xff; 580 | if (val < 16) { 581 | hexValue.append("0"); 582 | } 583 | hexValue.append(Integer.toHexString(val)); 584 | } 585 | 586 | result = hexValue.toString(); 587 | } catch (Exception e) { 588 | e.printStackTrace(); 589 | } 590 | return result; 591 | } 592 | 593 | 594 | /** 595 | * 判断给定的字符串是否以一个特定的字符串开头,忽略大小写 596 | * 597 | * @param sourceString 给定的字符串 598 | * @param newString 一个特定的字符串 599 | */ 600 | public static boolean startsWithIgnoreCase(String sourceString, String newString) { 601 | int newLength = newString.length(); 602 | int sourceLength = sourceString.length(); 603 | if (newLength == sourceLength) { 604 | return newString.equalsIgnoreCase(sourceString); 605 | } 606 | else if (newLength < sourceLength) { 607 | char[] newChars = new char[newLength]; 608 | sourceString.getChars(0, newLength, newChars, 0); 609 | return newString.equalsIgnoreCase(String.valueOf(newChars)); 610 | } 611 | else { 612 | return false; 613 | } 614 | } 615 | 616 | 617 | /** 618 | * 判断给定的字符串是否以一个特定的字符串结尾,忽略大小写 619 | * 620 | * @param sourceString 给定的字符串 621 | * @param newString 一个特定的字符串 622 | */ 623 | public static boolean endsWithIgnoreCase(String sourceString, String newString) { 624 | int newLength = newString.length(); 625 | int sourceLength = sourceString.length(); 626 | if (newLength == sourceLength) { 627 | return newString.equalsIgnoreCase(sourceString); 628 | } 629 | else if (newLength < sourceLength) { 630 | char[] newChars = new char[newLength]; 631 | sourceString.getChars(sourceLength - newLength, sourceLength, 632 | newChars, 0); 633 | return newString.equalsIgnoreCase(String.valueOf(newChars)); 634 | } 635 | else { 636 | return false; 637 | } 638 | } 639 | 640 | 641 | /** 642 | * 检查字符串长度,如果字符串的长度超过maxLength,就截取前maxLength个字符串并在末尾拼上appendString 643 | */ 644 | public static String checkLength(String string, int maxLength, String appendString) { 645 | if (string.length() > maxLength) { 646 | string = string.substring(0, maxLength); 647 | if (appendString != null) { 648 | string += appendString; 649 | } 650 | } 651 | return string; 652 | } 653 | 654 | 655 | /** 656 | * 检查字符串长度,如果字符串的长度超过maxLength,就截取前maxLength个字符串并在末尾拼上… 657 | */ 658 | public static String checkLength(String string, int maxLength) { 659 | return checkLength(string, maxLength, "…"); 660 | } 661 | } 662 | -------------------------------------------------------------------------------- /app/src/main/java/utils/ToastUtil.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import android.content.Context; 4 | import android.widget.Toast; 5 | 6 | /** 7 | * Toast统一管理类 8 | */ 9 | public class ToastUtil { 10 | 11 | public static boolean isShow = true; 12 | 13 | /*cannot be instantiated*/ 14 | private ToastUtil(){ 15 | throw new UnsupportedOperationException("cannot be instantiated"); 16 | } 17 | 18 | /** 19 | * 短时间显示Toast 20 | * 21 | * @param context 22 | * @param message 23 | */ 24 | public static void showShort(Context context, CharSequence message) { 25 | if (isShow) 26 | Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 27 | } 28 | 29 | /** 30 | * 短时间显示Toast 31 | * 32 | * @param context 33 | * @param message 34 | */ 35 | public static void showShort(Context context, int message) { 36 | if (isShow) 37 | Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 38 | } 39 | 40 | /** 41 | * 长时间显示Toast 42 | * 43 | * @param context 44 | * @param message 45 | */ 46 | public static void showLong(Context context, CharSequence message) { 47 | if (isShow) 48 | Toast.makeText(context, message, Toast.LENGTH_LONG).show(); 49 | } 50 | 51 | /** 52 | * 长时间显示Toast 53 | * 54 | * @param context 55 | * @param message 56 | */ 57 | public static void showLong(Context context, int message) { 58 | if (isShow) 59 | Toast.makeText(context, message, Toast.LENGTH_LONG).show(); 60 | } 61 | 62 | /** 63 | * 自定义显示Toast时间 64 | * 65 | * @param context 66 | * @param message 67 | * @param duration 68 | */ 69 | public static void show(Context context, CharSequence message, int duration) { 70 | if (isShow) 71 | Toast.makeText(context, message, duration).show(); 72 | } 73 | 74 | /** 75 | * 自定义显示Toast时间 76 | * 77 | * @param context 78 | * @param message 79 | * @param duration 80 | */ 81 | public static void show(Context context, int message, int duration) { 82 | if (isShow) 83 | Toast.makeText(context, message, duration).show(); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/utils/view/CheckBoxView.java: -------------------------------------------------------------------------------- 1 | package utils.view; 2 | 3 | import android.animation.ObjectAnimator; 4 | import android.content.Context; 5 | import android.content.res.TypedArray; 6 | import android.graphics.Bitmap; 7 | import android.graphics.Canvas; 8 | import android.graphics.Paint; 9 | import android.graphics.PorterDuff; 10 | import android.graphics.PorterDuffXfermode; 11 | import android.graphics.drawable.Drawable; 12 | import android.util.AttributeSet; 13 | import android.view.View; 14 | import android.widget.Checkable; 15 | 16 | import com.example.hjx.androidutils.R; 17 | 18 | /** 19 | * 自定义CheckBox 20 | */ 21 | public class CheckBoxView extends View implements Checkable{ 22 | 23 | private final static float BOUNCE_VALUE = 0.2f; 24 | 25 | private Drawable checkDrawable; 26 | 27 | private Paint bitmapPaint; 28 | private Paint bitmapEraser; 29 | private Paint checkEraser; 30 | private Paint borderPaint; 31 | 32 | private Bitmap drawBitmap; 33 | private Bitmap checkBitmap; 34 | private Canvas bitmapCanvas; 35 | private Canvas checkCanvas; 36 | 37 | private float progress; 38 | private ObjectAnimator checkAnim; 39 | 40 | private boolean attachedToWindow; 41 | private boolean isChecked; 42 | 43 | private int size = 22; 44 | private int bitmapColor = 0xFF3F51B5; 45 | private int borderColor = 0xFFFFFFFF; 46 | 47 | public CheckBoxView(Context context) { 48 | this(context, null); 49 | } 50 | 51 | public CheckBoxView(Context context, AttributeSet attrs) { 52 | this(context, attrs, 0); 53 | } 54 | 55 | public CheckBoxView(Context context, AttributeSet attrs, int defStyle) { 56 | super(context, attrs, defStyle); 57 | init(context, attrs); 58 | } 59 | 60 | private void init(Context context, AttributeSet attrs) { 61 | TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.CheckBoxView); 62 | size = ta.getDimensionPixelSize(R.styleable.CheckBoxView_size, dp(size)); 63 | bitmapColor = ta.getColor(R.styleable.CheckBoxView_color_background, bitmapColor); 64 | borderColor = ta.getColor(R.styleable.CheckBoxView_color_border, borderColor); 65 | 66 | bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 67 | bitmapEraser = new Paint(Paint.ANTI_ALIAS_FLAG); 68 | bitmapEraser.setColor(0); 69 | bitmapEraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 70 | checkEraser = new Paint(Paint.ANTI_ALIAS_FLAG); 71 | checkEraser.setColor(0); 72 | checkEraser.setStyle(Paint.Style.STROKE); 73 | checkEraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 74 | borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 75 | borderPaint.setStyle(Paint.Style.STROKE); 76 | borderPaint.setStrokeWidth(dp(2)); 77 | checkDrawable = context.getResources().getDrawable(R.mipmap.check); 78 | setVisibility(VISIBLE); 79 | ta.recycle(); 80 | } 81 | 82 | @Override 83 | public void setVisibility(int visibility) { 84 | super.setVisibility(visibility); 85 | if (visibility == VISIBLE && drawBitmap == null) { 86 | drawBitmap = Bitmap.createBitmap(dp(size), dp(size), Bitmap.Config.ARGB_8888); 87 | bitmapCanvas = new Canvas(drawBitmap); 88 | checkBitmap = Bitmap.createBitmap(dp(size), dp(size), Bitmap.Config.ARGB_8888); 89 | checkCanvas = new Canvas(checkBitmap); 90 | } 91 | } 92 | 93 | @Override 94 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 95 | int newSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.getMode(Math.min(widthMeasureSpec, heightMeasureSpec))); 96 | super.onMeasure(newSpec, newSpec); 97 | } 98 | 99 | @Override 100 | protected void onDraw(Canvas canvas) { 101 | if (getVisibility() != VISIBLE) { 102 | return; 103 | } 104 | checkEraser.setStrokeWidth(size); 105 | 106 | drawBitmap.eraseColor(0); 107 | float rad = getMeasuredWidth() / 2; 108 | 109 | float bitmapProgress = progress >= 0.5f ? 1.0f : progress / 0.5f; 110 | float checkProgress = progress < 0.5f ? 0.0f : (progress - 0.5f) / 0.5f; 111 | 112 | float p = isChecked ? progress : (1.0f - progress); 113 | 114 | if (p < BOUNCE_VALUE) { 115 | rad -= dp(2) * p ; 116 | } else if (p < BOUNCE_VALUE * 2) { 117 | rad -= dp(2) - dp(2) * p; 118 | } 119 | 120 | borderPaint.setColor(borderColor); 121 | canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad - dp(1), borderPaint); 122 | 123 | bitmapPaint.setColor(bitmapColor); 124 | 125 | bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad, bitmapPaint); 126 | bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad * (1 - bitmapProgress), bitmapEraser); 127 | canvas.drawBitmap(drawBitmap, 0, 0, null); 128 | 129 | checkBitmap.eraseColor(0); 130 | int w = checkDrawable.getIntrinsicWidth(); 131 | int h = checkDrawable.getIntrinsicHeight(); 132 | int x = (getMeasuredWidth() - w) / 2; 133 | int y = (getMeasuredHeight() - h) / 2; 134 | 135 | checkDrawable.setBounds(x, y , x + w, y + h ); 136 | checkDrawable.draw(checkCanvas); 137 | checkCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad * (1 - checkProgress), checkEraser); 138 | 139 | canvas.drawBitmap(checkBitmap, 0, 0, null); 140 | } 141 | 142 | @Override 143 | protected void onAttachedToWindow() { 144 | super.onAttachedToWindow(); 145 | attachedToWindow = true; 146 | } 147 | 148 | @Override 149 | protected void onDetachedFromWindow() { 150 | super.onDetachedFromWindow(); 151 | attachedToWindow = false; 152 | } 153 | 154 | 155 | public void setProgress(float value) { 156 | if (progress == value) { 157 | return; 158 | } 159 | progress = value; 160 | invalidate(); 161 | } 162 | 163 | public void setSize(int size) { 164 | this.size = size; 165 | } 166 | 167 | public float getProgress() { 168 | return progress; 169 | } 170 | 171 | public void setCheckedColor(int value) { 172 | bitmapColor = value; 173 | } 174 | 175 | public void setBorderColor(int value) { 176 | borderColor = value; 177 | borderPaint.setColor(borderColor); 178 | } 179 | 180 | private void cancelAnim() { 181 | if (checkAnim != null) { 182 | checkAnim.cancel(); 183 | } 184 | } 185 | 186 | private void addAnim(boolean isChecked) { 187 | checkAnim = ObjectAnimator.ofFloat(this, "progress", isChecked ? 1.0f : 0.0f); 188 | checkAnim.setDuration(300); 189 | checkAnim.start(); 190 | } 191 | 192 | public void setChecked(boolean checked, boolean animated) { 193 | if (checked == isChecked) { 194 | return; 195 | } 196 | isChecked = checked; 197 | 198 | if (attachedToWindow && animated) { 199 | addAnim(checked); 200 | } else { 201 | cancelAnim(); 202 | setProgress(checked ? 1.0f : 0.0f); 203 | } 204 | } 205 | 206 | 207 | @Override 208 | public void toggle() { 209 | setChecked(!isChecked); 210 | } 211 | 212 | @Override 213 | public void setChecked(boolean b) { 214 | setChecked(b, true); 215 | } 216 | 217 | @Override 218 | public boolean isChecked() { 219 | return isChecked; 220 | } 221 | 222 | public int dp(float value) { 223 | if (value == 0) { 224 | return 0; 225 | } 226 | float density = getContext().getResources().getDisplayMetrics().density; 227 | return (int) Math.ceil(density * value); 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HJXANDHMR/AndroidUtils/e31f90cbfc498fc918d37f4860a5cddbb29ea05b/app/src/main/res/mipmap-hdpi/check.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HJXANDHMR/AndroidUtils/e31f90cbfc498fc918d37f4860a5cddbb29ea05b/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HJXANDHMR/AndroidUtils/e31f90cbfc498fc918d37f4860a5cddbb29ea05b/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HJXANDHMR/AndroidUtils/e31f90cbfc498fc918d37f4860a5cddbb29ea05b/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HJXANDHMR/AndroidUtils/e31f90cbfc498fc918d37f4860a5cddbb29ea05b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AndroidUtils 3 | 4 | Hello world! 5 | Settings 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.0.0' 9 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' 10 | 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | jcenter() 19 | } 20 | } 21 | 22 | task clean(type: Delete) { 23 | delete rootProject.buildDir 24 | } 25 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HJXANDHMR/AndroidUtils/e31f90cbfc498fc918d37f4860a5cddbb29ea05b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------