10 | * author: Blankj 11 | * blog : http://blankj.com 12 | * time : 2016/8/23 13 | * desc : SDCard单元测试 14 | *15 | */ 16 | @RunWith(RobolectricTestRunner.class) 17 | @Config(manifest = Config.NONE) 18 | public class SDCardUtilsTest { 19 | 20 | @Test 21 | public void testIsSDCardEnable() throws Exception { 22 | System.out.println(SDCardUtils.isSDCardEnable()); 23 | } 24 | 25 | @Test 26 | public void testGetSDCardPath() throws Exception { 27 | System.out.println(SDCardUtils.getSDCardPath()); 28 | } 29 | } -------------------------------------------------------------------------------- /utilcode/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 G:\Android_IDE\ADT\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 | 19 | 20 | #-keep class com.blankj.utilcode.** { *; } 21 | #-keep classmembers class com.blankj.utilcode.** { *; } 22 | #-dontwarn com.blankj.utilcode.** -------------------------------------------------------------------------------- /utilcode/src/test/java/com/blankj/utilcode/utils/TestUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.content.Context; 4 | 5 | import org.junit.runner.RunWith; 6 | import org.robolectric.RobolectricTestRunner; 7 | import org.robolectric.annotation.Config; 8 | import org.robolectric.shadows.ShadowApplication; 9 | 10 | import java.io.File; 11 | 12 | /** 13 | *
14 | * author: Blankj 15 | * blog : http://blankj.com 16 | * time : 2016/8/21 17 | * desc : 单元测试工具类 18 | *19 | */ 20 | @RunWith(RobolectricTestRunner.class) 21 | @Config(manifest = Config.NONE) 22 | public class TestUtils { 23 | 24 | private TestUtils() { 25 | throw new UnsupportedOperationException("u can't fuck me..."); 26 | } 27 | 28 | public static final char SEP = File.separatorChar; 29 | 30 | public static final String BASEPATH = System.getProperty("user.dir") 31 | + SEP + "src" + SEP + "test" + SEP + "res" + SEP; 32 | 33 | public static Context getContext() { 34 | return ShadowApplication.getInstance().getApplicationContext(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/UnclassifiedUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.app.ActivityManager; 4 | import android.app.ActivityManager.RunningServiceInfo; 5 | import android.content.ComponentName; 6 | import android.content.Context; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *
12 | * author: Blankj 13 | * blog : http://blankj.com 14 | * time : 2016/8/2 15 | * desc : 未归类工具类 16 | *17 | */ 18 | public class UnclassifiedUtils { 19 | 20 | private UnclassifiedUtils() { 21 | throw new UnsupportedOperationException("u can't fuck me..."); 22 | } 23 | 24 | /** 25 | * 获取服务是否开启 26 | * 27 | * @param context 上下文 28 | * @param className 完整包名的服务类名 29 | * @return {@code true}: 是
10 | * author: Blankj 11 | * blog : http://blankj.com 12 | * time : 2016/8/16 13 | * desc : StringUtils单元测试 14 | *15 | */ 16 | public class StringUtilsTest { 17 | 18 | @Test 19 | public void testIsEmpty() throws Exception { 20 | assertThat(isEmpty("")).isTrue(); 21 | assertThat(isEmpty(null)).isTrue(); 22 | assertThat(isEmpty(" ")).isFalse(); 23 | } 24 | 25 | @Test 26 | public void testIsSpace() throws Exception { 27 | assertThat(isSpace("")).isTrue(); 28 | assertThat(isSpace(null)).isTrue(); 29 | assertThat(isSpace(" ")).isTrue(); 30 | assertThat(isSpace(" ")).isFalse(); 31 | } 32 | 33 | @Test 34 | public void testNull2Length0() throws Exception { 35 | assertThat(null2Length0(null)).isEqualTo(""); 36 | } 37 | 38 | @Test 39 | public void testLength() throws Exception { 40 | assertThat(length(null)).isEqualTo(0); 41 | assertThat(length("")).isEqualTo(0); 42 | assertThat(length("blankj")).isEqualTo(6); 43 | } 44 | 45 | @Test 46 | public void testUpperFirstLetter() throws Exception { 47 | assertThat(upperFirstLetter("blankj")).isEqualTo("Blankj"); 48 | assertThat(upperFirstLetter("Blankj")).isEqualTo("Blankj"); 49 | assertThat(upperFirstLetter("1Blankj")).isEqualTo("1Blankj"); 50 | } 51 | 52 | @Test 53 | public void testLowerFirstLetter() throws Exception { 54 | assertThat(lowerFirstLetter("blankj")).isEqualTo("blankj"); 55 | assertThat(lowerFirstLetter("Blankj")).isEqualTo("blankj"); 56 | assertThat(lowerFirstLetter("1blankj")).isEqualTo("1blankj"); 57 | } 58 | 59 | @Test 60 | public void testToDBC() throws Exception { 61 | assertThat(toDBC(" ,.&")).isEqualTo(" ,.&"); 62 | } 63 | 64 | @Test 65 | public void testToSBC() throws Exception { 66 | assertThat(toSBC(" ,.&")).isEqualTo(" ,.&"); 67 | } 68 | } -------------------------------------------------------------------------------- /utilcode/src/test/java/com/blankj/utilcode/utils/ConvertUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import static com.blankj.utilcode.utils.ConvertUtils.bytes2Chars; 7 | import static com.blankj.utilcode.utils.ConvertUtils.bytes2HexString; 8 | import static com.blankj.utilcode.utils.ConvertUtils.bytes2InputStream; 9 | import static com.blankj.utilcode.utils.ConvertUtils.chars2Bytes; 10 | import static com.blankj.utilcode.utils.ConvertUtils.hexString2Bytes; 11 | import static com.blankj.utilcode.utils.ConvertUtils.inputStream2Bytes; 12 | import static com.blankj.utilcode.utils.ConvertUtils.inputStream2String; 13 | import static com.blankj.utilcode.utils.ConvertUtils.string2InputStream; 14 | import static com.google.common.truth.Truth.assertThat; 15 | 16 | 17 | /** 18 | *
19 | * author: Blankj 20 | * blog : http://blankj.com 21 | * time : 2016/8/13 22 | * desc : ConvertUtils单元测试 23 | *24 | */ 25 | public class ConvertUtilsTest { 26 | 27 | byte[] mBytes = new byte[]{0x00, 0x08, (byte) 0xdb, 0x33, 0x45, (byte) 0xab, 0x02, 0x23}; 28 | String hexString = "0008DB3345AB0223"; 29 | 30 | @Test 31 | public void testBytes2HexString() throws Exception { 32 | assertThat(bytes2HexString(mBytes)).isEqualTo(hexString); 33 | } 34 | 35 | @Test 36 | public void testHexString2Bytes() throws Exception { 37 | assertThat(hexString2Bytes(hexString)).isEqualTo(mBytes); 38 | } 39 | 40 | char[] mChars1 = new char[]{'0', '1', '2'}; 41 | byte[] mBytes1 = new byte[]{48, 49, 50}; 42 | 43 | @Test 44 | public void testChars2Bytes() throws Exception { 45 | assertThat(chars2Bytes(mChars1)).isEqualTo(mBytes1); 46 | } 47 | 48 | @Test 49 | public void testBytes2Chars() throws Exception { 50 | assertThat(bytes2Chars(mBytes1)).isEqualTo(mChars1); 51 | } 52 | 53 | @Test 54 | public void testInputStream2BytesAndBytes2InputStream() throws Exception { 55 | String string = "this is test string"; 56 | assertThat(new String(inputStream2Bytes( 57 | bytes2InputStream(string.getBytes("UTF-8"))))) 58 | .isEqualTo(string); 59 | } 60 | 61 | @Test 62 | public void testInputStream2StringAndString2InputStream() throws Exception { 63 | String string = "this is test string"; 64 | assertThat(inputStream2String( 65 | string2InputStream(string, "UTF-8") 66 | , "UTF-8")).isEqualTo(string); 67 | } 68 | } -------------------------------------------------------------------------------- /utilcode/src/test/java/com/blankj/utilcode/utils/ImageUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.robolectric.RobolectricTestRunner; 8 | import org.robolectric.annotation.Config; 9 | 10 | import static com.blankj.utilcode.utils.TestUtils.BASEPATH; 11 | import static com.blankj.utilcode.utils.TestUtils.SEP; 12 | 13 | /** 14 | *
15 | * author: Blankj 16 | * blog : http://blankj.com 17 | * time : 2016/8/30 18 | * desc : ImageUtils单元测试 19 | *20 | */ 21 | @RunWith(RobolectricTestRunner.class) 22 | @Config(manifest = Config.NONE) 23 | public class ImageUtilsTest { 24 | 25 | String path = BASEPATH + "image" + SEP; 26 | 27 | @Test 28 | public void testBitmap2Bytes() throws Exception { 29 | FileUtils.createOrExistsFile(path + "new1.png"); 30 | Bitmap bitmap = ImageUtils.getBitmapByFile(path + "lena.png"); 31 | System.out.println(ImageUtils.save(bitmap, path + "new1.png", Bitmap.CompressFormat.PNG)); 32 | } 33 | 34 | @Test 35 | public void testBytes2Bitmap() throws Exception { 36 | 37 | } 38 | 39 | @Test 40 | public void testDrawable2Bitmap() throws Exception { 41 | 42 | } 43 | 44 | @Test 45 | public void testBitmap2Drawable() throws Exception { 46 | 47 | } 48 | 49 | @Test 50 | public void testDrawable2Bytes() throws Exception { 51 | 52 | } 53 | 54 | @Test 55 | public void testBytes2Drawable() throws Exception { 56 | 57 | } 58 | 59 | @Test 60 | public void testGetBitmap() throws Exception { 61 | 62 | } 63 | 64 | @Test 65 | public void testScaleImage() throws Exception { 66 | 67 | } 68 | 69 | @Test 70 | public void testToRound() throws Exception { 71 | 72 | } 73 | 74 | @Test 75 | public void testToRoundCorner() throws Exception { 76 | 77 | } 78 | 79 | @Test 80 | public void testFastBlur() throws Exception { 81 | 82 | } 83 | 84 | @Test 85 | public void testRenderScriptBlur() throws Exception { 86 | 87 | } 88 | 89 | @Test 90 | public void testStackBlur() throws Exception { 91 | 92 | } 93 | 94 | @Test 95 | public void testAddFrame() throws Exception { 96 | 97 | } 98 | 99 | @Test 100 | public void testAddReflection() throws Exception { 101 | 102 | } 103 | 104 | @Test 105 | public void testSaveBitmap() throws Exception { 106 | 107 | } 108 | } -------------------------------------------------------------------------------- /utilcode/src/test/java/com/blankj/utilcode/utils/EncodeUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.robolectric.RobolectricTestRunner; 6 | import org.robolectric.annotation.Config; 7 | 8 | import static com.blankj.utilcode.utils.EncodeUtils.*; 9 | import static com.google.common.truth.Truth.assertThat; 10 | 11 | /** 12 | *
13 | * author: Blankj 14 | * blog : http://blankj.com 15 | * time : 2016/8/12 16 | * desc : EncodeUtils单元测试 17 | *18 | */ 19 | @RunWith(RobolectricTestRunner.class) 20 | @Config(manifest = Config.NONE) 21 | public class EncodeUtilsTest { 22 | 23 | String urlEncodeString = "%E5%93%88%E5%93%88%E5%93%88"; 24 | String html = "" + 25 | "" + 26 | "
body 元素的内容会显示在浏览器中。
" + 30 | "title 元素的内容会显示在浏览器的标题栏中。
" + 31 | "" + 32 | ""; 33 | String encodeHtml = "<html><head><title>我的第一个 HTML 页面</title></head><body><p>body 元素的内容会显示在浏览器中。</p><p>title 元素的内容会显示在浏览器的标题栏中。</p></body></html>"; 34 | 35 | @Test 36 | public void testUrlEncode() throws Exception { 37 | assertThat(urlEncode("哈哈哈")).isEqualTo(urlEncodeString); 38 | assertThat(urlEncode("哈哈哈", "UTF-8")).isEqualTo(urlEncodeString); 39 | } 40 | 41 | @Test 42 | public void testUrlDecode() throws Exception { 43 | assertThat(urlDecode(urlEncodeString)).isEqualTo("哈哈哈"); 44 | assertThat(urlDecode(urlEncodeString, "UTF-8")).isEqualTo("哈哈哈"); 45 | } 46 | 47 | @Test 48 | public void testBase64EncodeAndDecode() throws Exception { 49 | assertThat(base64Decode(base64Encode("blankj"))) 50 | .isEqualTo("blankj".getBytes()); 51 | assertThat(base64Decode(base64Encode2String("blankj".getBytes()))) 52 | .isEqualTo("blankj".getBytes()); 53 | assertThat(base64Encode2String("blankj".getBytes())) 54 | .isEqualTo("Ymxhbmtq"); 55 | assertThat(base64Encode("blankj".getBytes())) 56 | .isEqualTo("Ymxhbmtq".getBytes()); 57 | } 58 | 59 | @Test 60 | public void testHtmlEncode() throws Exception { 61 | assertThat(htmlEncode(html)).isEqualTo(encodeHtml); 62 | } 63 | 64 | @Test 65 | public void testHtmlDecode() throws Exception { 66 | assertThat(htmlDecode(encodeHtml)).isEqualTo(html); 67 | } 68 | } -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/DeviceUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.content.Context; 4 | import android.net.wifi.WifiInfo; 5 | import android.net.wifi.WifiManager; 6 | import android.os.Build; 7 | import android.os.Environment; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.io.InputStreamReader; 12 | import java.io.LineNumberReader; 13 | 14 | /** 15 | *16 | * author: Blankj 17 | * blog : http://blankj.com 18 | * time : 2016/8/1 19 | * desc : 设备相关工具类 20 | *21 | */ 22 | public class DeviceUtils { 23 | 24 | private DeviceUtils() { 25 | throw new UnsupportedOperationException("u can't fuck me..."); 26 | } 27 | 28 | /** 29 | * 获取设备MAC地址 30 | *
需添加权限 {@code
需添加权限 {@code
15 | * author: Blankj 16 | * blog : http://blankj.com 17 | * time : 2016/8/22 18 | * desc : SPUtils单元测试 19 | *20 | */ 21 | @RunWith(RobolectricTestRunner.class) 22 | @Config(manifest = Config.NONE) 23 | public class SPUtilsTest { 24 | 25 | SPUtils spUtils; 26 | 27 | @Before 28 | public void setUp() throws Exception { 29 | if (spUtils == null) { 30 | spUtils = new SPUtils(TestUtils.getContext(), "test"); 31 | spUtils.putString("stringKey", "stringVal"); 32 | spUtils.putInt("intKey", 1); 33 | spUtils.putLong("longKey", 1L); 34 | spUtils.putFloat("floatKey", 1f); 35 | spUtils.putBoolean("booleanKey", true); 36 | } 37 | } 38 | 39 | @Test 40 | public void testGetString() throws Exception { 41 | assertThat(spUtils.getString("stringKey")).isEqualTo("stringVal"); 42 | assertThat(spUtils.getString("stringKey1", "stringVal1")).isEqualTo("stringVal1"); 43 | assertThat(spUtils.getString("stringKey1")).isNull(); 44 | } 45 | 46 | @Test 47 | public void testGetInt() throws Exception { 48 | assertThat(spUtils.getInt("intKey")).isEqualTo(1); 49 | assertThat(spUtils.getInt("intKey1", 10086)).isEqualTo(10086); 50 | assertThat(spUtils.getInt("intKey1")).isEqualTo(-1); 51 | } 52 | 53 | @Test 54 | public void testGetLong() throws Exception { 55 | assertThat(spUtils.getLong("longKey")).isEqualTo(1L); 56 | assertThat(spUtils.getLong("longKey1", 10086L)).isEqualTo(10086L); 57 | assertThat(spUtils.getLong("longKey1")).isEqualTo(-1L); 58 | } 59 | 60 | @Test 61 | public void testGetFloat() throws Exception { 62 | assertThat(spUtils.getFloat("floatKey") - 1.f).isWithin(0.f); 63 | assertThat(spUtils.getFloat("floatKey1", 10086f) - 10086f).isWithin(0.f); 64 | assertThat(spUtils.getFloat("floatKey1") + 1.f).isWithin(0.f); 65 | } 66 | 67 | @Test 68 | public void testGetBoolean() throws Exception { 69 | assertThat(spUtils.getBoolean("booleanKey")).isTrue(); 70 | assertThat(spUtils.getBoolean("booleanKey1", true)).isTrue(); 71 | assertThat(spUtils.getBoolean("booleanKey1")).isFalse(); 72 | } 73 | 74 | @Test 75 | public void testGetAll() throws Exception { 76 | Map
10 | * author: Blankj 11 | * blog : http://blankj.com 12 | * time : 2016/8/16 13 | * desc : RegularUtils单元测试 14 | *15 | */ 16 | public class RegularUtilsTest { 17 | 18 | @Test 19 | public void testIsMobileSimple() throws Exception { 20 | assertThat(isMobileSimple("11111111111")).isTrue(); 21 | } 22 | 23 | @Test 24 | public void testIsMobileExact() throws Exception { 25 | assertThat(isMobileExact("11111111111")).isFalse(); 26 | assertThat(isMobileExact("13888880000")).isTrue(); 27 | } 28 | 29 | @Test 30 | public void testIsTel() throws Exception { 31 | assertThat(isTel("033-88888888")).isTrue(); 32 | assertThat(isTel("033-7777777")).isTrue(); 33 | assertThat(isTel("0444-88888888")).isTrue(); 34 | assertThat(isTel("0444-7777777")).isTrue(); 35 | assertThat(isTel("033 88888888")).isTrue(); 36 | assertThat(isTel("033 7777777")).isTrue(); 37 | assertThat(isTel("0444 88888888")).isTrue(); 38 | assertThat(isTel("0444 7777777")).isTrue(); 39 | assertThat(isTel("03388888888")).isTrue(); 40 | assertThat(isTel("0337777777")).isTrue(); 41 | assertThat(isTel("044488888888")).isTrue(); 42 | assertThat(isTel("04447777777")).isTrue(); 43 | 44 | assertThat(isTel("133-88888888")).isFalse(); 45 | assertThat(isTel("033-666666")).isFalse(); 46 | assertThat(isTel("0444-999999999")).isFalse(); 47 | } 48 | 49 | @Test 50 | public void testIsIDCard() throws Exception { 51 | assertThat(isIDCard18("33698418400112523x")).isTrue(); 52 | assertThat(isIDCard18("336984184001125233")).isTrue(); 53 | assertThat(isIDCard18("336984184021125233")).isFalse(); 54 | } 55 | 56 | @Test 57 | public void testIsEmail() throws Exception { 58 | assertThat(isEmail("blankj@qq.com")).isTrue(); 59 | assertThat(isEmail("blankj@qq")).isFalse(); 60 | } 61 | 62 | @Test 63 | public void testIsURL() throws Exception { 64 | assertThat(isURL("http://blankj.com")).isTrue(); 65 | assertThat(isURL("http://blank")).isFalse(); 66 | } 67 | 68 | @Test 69 | public void testIsChz() throws Exception { 70 | assertThat(isChz("我")).isTrue(); 71 | assertThat(isChz("wo")).isFalse(); 72 | } 73 | 74 | @Test 75 | public void testIsUsername() throws Exception { 76 | assertThat(isUsername("小明233333")).isTrue(); 77 | assertThat(isUsername("小明")).isFalse(); 78 | assertThat(isUsername("小明233333_")).isFalse(); 79 | } 80 | 81 | @Test 82 | public void testIsDate() throws Exception { 83 | assertThat(isDate("2016-08-16")).isTrue(); 84 | assertThat(isDate("2016-02-29")).isTrue(); 85 | assertThat(isDate("2015-02-29")).isFalse(); 86 | assertThat(isDate("2016-8-16")).isFalse(); 87 | } 88 | 89 | @Test 90 | public void testIsIP() throws Exception { 91 | assertThat(isIP("255.255.255.0")).isTrue(); 92 | assertThat(isIP("256.255.255.0")).isFalse(); 93 | } 94 | 95 | @Test 96 | public void testIsMatch() throws Exception { 97 | assertThat(isMatch("\\d?", "1")).isTrue(); 98 | assertThat(isMatch("\\d?", "a")).isFalse(); 99 | } 100 | } -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | /** 4 | *
5 | * author: Blankj 6 | * blog : http://blankj.com 7 | * time : 2016/8/16 8 | * desc : 字符串相关工具类 9 | *10 | */ 11 | public class StringUtils { 12 | 13 | private StringUtils() { 14 | throw new UnsupportedOperationException("u can't fuck me..."); 15 | } 16 | 17 | /** 18 | * 判断字符串是否为null或长度为0 19 | * 20 | * @param string 待校验字符串 21 | * @return {@code true}: 空
15 | * author: Blankj 16 | * blog : http://blankj.com 17 | * time : 2016/8/12 18 | * desc : TimeUtils单元测试 19 | *20 | */ 21 | public class TimeUtilsTest { 22 | 23 | 24 | SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzzz", Locale.getDefault()); 25 | long milliseconds = 1470991049000L; 26 | Date timeDate = new Date(milliseconds); 27 | String timeString = "2016-08-12 16:37:29"; 28 | String myTimeString = "2016-08-12 16:37:29 中国标准时间"; 29 | String timeString0 = "2016-08-12 16:00:00"; 30 | String timeString1 = "2016-08-12 17:10:10"; 31 | String myTimeString0 = "2016-08-12 16:00:00 中国标准时间"; 32 | String myTimeString1 = "2016-08-12 17:10:10 中国标准时间"; 33 | 34 | 35 | @Test 36 | public void testMilliseconds2String() throws Exception { 37 | assertThat(milliseconds2String(milliseconds)).isEqualTo(timeString); 38 | assertThat(milliseconds2String(milliseconds, myFormat)).isEqualTo(myTimeString); 39 | } 40 | 41 | @Test 42 | public void testString2Milliseconds() throws Exception { 43 | assertThat(string2Milliseconds(timeString)).isEqualTo(milliseconds); 44 | assertThat(string2Milliseconds(myTimeString, myFormat)).isEqualTo(milliseconds); 45 | } 46 | 47 | @Test 48 | public void testString2Date() throws Exception { 49 | assertThat(string2Date(timeString)).isEqualTo(timeDate); 50 | assertThat(string2Date(myTimeString, myFormat)).isEqualTo(timeDate); 51 | } 52 | 53 | @Test 54 | public void testDate2String() throws Exception { 55 | assertThat(date2String(timeDate)).isEqualTo(timeString); 56 | assertThat(date2String(timeDate, myFormat)).isEqualTo(myTimeString); 57 | } 58 | 59 | @Test 60 | public void testDate2Milliseconds() throws Exception { 61 | assertThat(date2Milliseconds(timeDate)).isEqualTo(milliseconds); 62 | } 63 | 64 | @Test 65 | public void testMilliseconds2Date() throws Exception { 66 | assertThat(milliseconds2Date(milliseconds)).isEqualTo(timeDate); 67 | } 68 | 69 | @Test 70 | public void testGetIntervalTime() throws Exception { 71 | assertThat(getIntervalTime(timeString0, timeString1, ConstUtils.TimeUnit.SEC)).isEqualTo(4210); 72 | assertThat(getIntervalTime(myTimeString0, myTimeString1, ConstUtils.TimeUnit.SEC, myFormat)).isEqualTo(4210); 73 | assertThat(getIntervalTime(new Date(4210000), new Date(0), ConstUtils.TimeUnit.SEC)).isEqualTo(4210); 74 | } 75 | 76 | @Test 77 | public void testGetCurTimeMills() throws Exception { 78 | long interval = getCurTimeMills() - System.currentTimeMillis(); 79 | assertThat(interval).isLessThan(10L); 80 | } 81 | 82 | @Test 83 | public void testGetCurTimeString() throws Exception { 84 | System.out.println(getCurTimeString()); 85 | System.out.println(getCurTimeString(myFormat)); 86 | } 87 | 88 | @Test 89 | public void testGetCurTimeDate() throws Exception { 90 | 91 | } 92 | 93 | @Test 94 | public void testGetIntervalByNow() throws Exception { 95 | 96 | } 97 | 98 | @Test 99 | public void testIsLeapYear() throws Exception { 100 | assertThat(isLeapYear(2012)).isEqualTo(true); 101 | assertThat(isLeapYear(2000)).isEqualTo(true); 102 | assertThat(isLeapYear(1900)).isEqualTo(false); 103 | } 104 | } -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/ConstUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | /** 4 | *
5 | * author: Blankj 6 | * blog : http://blankj.com 7 | * time : 2016/8/11 8 | * desc : 常量相关工具类 9 | *10 | */ 11 | public class ConstUtils { 12 | 13 | private ConstUtils() { 14 | throw new UnsupportedOperationException("u can't fuck me..."); 15 | } 16 | 17 | /******************** 存储相关常量 ********************/ 18 | /** 19 | * Byte与Byte的倍数 20 | */ 21 | public static final int BYTE = 1; 22 | /** 23 | * KB与Byte的倍数 24 | */ 25 | public static final int KB = 1024; 26 | /** 27 | * MB与Byte的倍数 28 | */ 29 | public static final int MB = 1048576; 30 | /** 31 | * GB与Byte的倍数 32 | */ 33 | public static final int GB = 1073741824; 34 | 35 | public enum MemoryUnit { 36 | BYTE, 37 | KB, 38 | MB, 39 | GB 40 | } 41 | 42 | /******************** 时间相关常量 ********************/ 43 | /** 44 | * 毫秒与毫秒的倍数 45 | */ 46 | public static final int MSEC = 1; 47 | /** 48 | * 秒与毫秒的倍数 49 | */ 50 | public static final int SEC = 1000; 51 | /** 52 | * 分与毫秒的倍数 53 | */ 54 | public static final int MIN = 60000; 55 | /** 56 | * 时与毫秒的倍数 57 | */ 58 | public static final int HOUR = 3600000; 59 | /** 60 | * 天与毫秒的倍数 61 | */ 62 | public static final int DAY = 86400000; 63 | 64 | public enum TimeUnit { 65 | MSEC, 66 | SEC, 67 | MIN, 68 | HOUR, 69 | DAY 70 | } 71 | 72 | /******************** 正则相关常量 ********************/ 73 | /** 74 | * 正则:手机号(简单) 75 | */ 76 | public static final String REGEX_MOBILE_SIMPLE = "^[1]\\d{10}$"; 77 | /** 78 | * 正则:手机号(精确) 79 | *
移动:134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188
80 | *联通:130、131、132、145、155、156、175、176、185、186
81 | *电信:133、153、173、177、180、181、189
82 | *全球星:1349
83 | *虚拟运营商:170
84 | */ 85 | public static final String REGEX_MOBILE_EXACT = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|(147))\\d{8}$"; 86 | /** 87 | * 正则:电话号码 88 | */ 89 | public static final String REGEX_TEL = "^0\\d{2,3}[- ]?\\d{7,8}"; 90 | /** 91 | * 正则:身份证号码15位 92 | */ 93 | public static final String REGEX_IDCARD15 = "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$"; 94 | /** 95 | * 正则:身份证号码18位 96 | */ 97 | public static final String REGEX_IDCARD18 = "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9Xx])$"; 98 | /** 99 | * 正则:邮箱 100 | */ 101 | public static final String REGEX_EMAIL = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"; 102 | /** 103 | * 正则:URL 104 | */ 105 | public static final String REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?"; 106 | /** 107 | * 正则:汉字 108 | */ 109 | public static final String REGEX_CHZ = "^[\\u4e00-\\u9fa5]+$"; 110 | /** 111 | * 正则:用户名,取值范围为a-z,A-Z,0-9,"_",汉字,不能以"_"结尾,用户名必须是6-20位 112 | */ 113 | public static final String REGEX_USERNAME = "^[\\w\\u4e00-\\u9fa5]{6,20}(? 9 | * author: Blankj 10 | * blog : http://blankj.com 11 | * time : 2016/8/2 12 | * desc : 正则相关工具类 13 | * 14 | */ 15 | public class RegularUtils { 16 | 17 | private RegularUtils() { 18 | throw new UnsupportedOperationException("u can't fuck me..."); 19 | } 20 | 21 | /** 22 | * If u want more please visit http://toutiao.com/i6231678548520731137/ 23 | */ 24 | 25 | /** 26 | * 验证手机号(简单) 27 | * 28 | * @param string 待验证文本 29 | * @return {@code true}: 匹配取值范围为a-z,A-Z,0-9,"_",汉字,不能以"_"结尾,用户名必须是6-20位
108 | * 109 | * @param string 待验证文本 110 | * @return {@code true}: 匹配11 | * author: Blankj 12 | * blog : http://blankj.com 13 | * time : 2016/8/2 14 | * desc : 尺寸相关工具类 15 | *16 | */ 17 | public class SizeUtils { 18 | 19 | private SizeUtils() { 20 | throw new UnsupportedOperationException("u can't fuck me..."); 21 | } 22 | 23 | /** 24 | * dp转px 25 | * 26 | * @param context 上下文 27 | * @param dpValue dp值 28 | * @return px值 29 | */ 30 | public static int dp2px(Context context, float dpValue) { 31 | final float scale = context.getResources().getDisplayMetrics().density; 32 | return (int) (dpValue * scale + 0.5f); 33 | } 34 | 35 | /** 36 | * px转dp 37 | * 38 | * @param context 上下文 39 | * @param pxValue px值 40 | * @return dp值 41 | */ 42 | public static int px2dp(Context context, float pxValue) { 43 | final float scale = context.getResources().getDisplayMetrics().density; 44 | return (int) (pxValue / scale + 0.5f); 45 | } 46 | 47 | /** 48 | * sp转px 49 | * 50 | * @param context 上下文 51 | * @param spValue sp值 52 | * @return px值 53 | */ 54 | public static int sp2px(Context context, float spValue) { 55 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 56 | return (int) (spValue * fontScale + 0.5f); 57 | } 58 | 59 | /** 60 | * px转sp 61 | * 62 | * @param context 上下文 63 | * @param pxValue px值 64 | * @return sp值 65 | */ 66 | public static int px2sp(Context context, float pxValue) { 67 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 68 | return (int) (pxValue / fontScale + 0.5f); 69 | } 70 | 71 | /** 72 | * 各种单位转换 73 | *
该方法存在于TypedValue
74 | * 75 | * @param unit 单位 76 | * @param value 值 77 | * @param metrics DisplayMetrics 78 | * @return 转换结果 79 | */ 80 | public static float applyDimension(int unit, float value, DisplayMetrics metrics) { 81 | switch (unit) { 82 | case TypedValue.COMPLEX_UNIT_PX: 83 | return value; 84 | case TypedValue.COMPLEX_UNIT_DIP: 85 | return value * metrics.density; 86 | case TypedValue.COMPLEX_UNIT_SP: 87 | return value * metrics.scaledDensity; 88 | case TypedValue.COMPLEX_UNIT_PT: 89 | return value * metrics.xdpi * (1.0f / 72); 90 | case TypedValue.COMPLEX_UNIT_IN: 91 | return value * metrics.xdpi; 92 | case TypedValue.COMPLEX_UNIT_MM: 93 | return value * metrics.xdpi * (1.0f / 25.4f); 94 | } 95 | return 0; 96 | } 97 | 98 | /** 99 | * 在onCreate()即可强行获取View的尺寸 100 | *需回调onGetSizeListener接口,在onGetSize中获取view宽高
101 | *用法示例如下所示
102 | *{@code
103 | * SizeUtils.forceGetViewSize(view);
104 | * SizeUtils.setListener(new SizeUtils.onGetSizeListener() {
105 | * public void onGetSize(View view) {
106 | * Log.d("tag", view.getWidth() + " " + view.getHeight());
107 | * }
108 | * });}
109 | *
110 | *
111 | * @param view 视图
112 | */
113 | public static void forceGetViewSize(final View view) {
114 | view.post(new Runnable() {
115 | @Override
116 | public void run() {
117 | if (mListener != null) {
118 | mListener.onGetSize(view);
119 | }
120 | }
121 | });
122 | }
123 |
124 | /**
125 | * 获取到View尺寸的监听
126 | */
127 | public interface onGetSizeListener {
128 | void onGetSize(View view);
129 | }
130 |
131 | public static void setListener(onGetSizeListener listener) {
132 | mListener = listener;
133 | }
134 |
135 | private static onGetSizeListener mListener;
136 |
137 | /**
138 | * ListView中提前测量View尺寸,如headerView
139 | * 用的时候去掉注释拷贝到ListView中即可
140 | *参照以下注释代码
141 | * 142 | * @param view 视图 143 | */ 144 | public static void measureViewInLV(View view) { 145 | Log.i("tips", "U should copy the following code."); 146 | /* 147 | ViewGroup.LayoutParams p = view.getLayoutParams(); 148 | if (p == null) { 149 | p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 150 | ViewGroup.LayoutParams.WRAP_CONTENT); 151 | } 152 | int width = ViewGroup.getChildMeasureSpec(0, 0, p.width); 153 | int height; 154 | int tempHeight = p.height; 155 | if (tempHeight > 0) { 156 | height = MeasureSpec.makeMeasureSpec(tempHeight, 157 | MeasureSpec.EXACTLY); 158 | } else { 159 | height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 160 | } 161 | view.measure(width, height); 162 | */ 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/KeyboardUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.view.inputmethod.InputMethodManager; 8 | import android.widget.EditText; 9 | 10 | /** 11 | *12 | * author: Blankj 13 | * blog : http://blankj.com 14 | * time : 2016/8/2 15 | * desc : 键盘相关工具类 16 | *17 | */ 18 | public class KeyboardUtils { 19 | 20 | private KeyboardUtils() { 21 | throw new UnsupportedOperationException("u can't fuck me..."); 22 | } 23 | 24 | /** 25 | * 避免输入法面板遮挡 26 | *
在manifest.xml中activity中设置
27 | *android:windowSoftInputMode="stateVisible|adjustResize"
28 | */ 29 | 30 | /** 31 | * 动态隐藏软键盘 32 | * 33 | * @param activity activity 34 | */ 35 | public static void hideSoftInput(Activity activity) { 36 | View view = activity.getWindow().peekDecorView(); 37 | if (view != null) { 38 | InputMethodManager inputmanger = (InputMethodManager) activity 39 | .getSystemService(Context.INPUT_METHOD_SERVICE); 40 | inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0); 41 | } 42 | } 43 | 44 | /** 45 | * 动态隐藏软键盘 46 | * 47 | * @param context 上下文 48 | * @param edit 输入框 49 | */ 50 | public static void hideSoftInput(Context context, EditText edit) { 51 | edit.clearFocus(); 52 | InputMethodManager inputmanger = (InputMethodManager) context 53 | .getSystemService(Context.INPUT_METHOD_SERVICE); 54 | inputmanger.hideSoftInputFromWindow(edit.getWindowToken(), 0); 55 | } 56 | 57 | /** 58 | * 点击屏幕空白区域隐藏软键盘(方法1) 59 | *在onTouch中处理,未获焦点则隐藏
60 | *参照以下注释代码
61 | */ 62 | public static void clickBlankArea2HideSoftInput0() { 63 | Log.i("tips", "U should copy the following code."); 64 | /* 65 | @Override 66 | public boolean onTouchEvent (MotionEvent event){ 67 | if (null != this.getCurrentFocus()) { 68 | InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); 69 | return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0); 70 | } 71 | return super.onTouchEvent(event); 72 | } 73 | */ 74 | } 75 | 76 | /** 77 | * 点击屏幕空白区域隐藏软键盘(方法2) 78 | *根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘
79 | *需重写dispatchTouchEvent
80 | *参照以下注释代码
81 | */ 82 | public static void clickBlankArea2HideSoftInput1() { 83 | Log.i("tips", "U should copy the following code."); 84 | /* 85 | @Override 86 | public boolean dispatchTouchEvent(MotionEvent ev) { 87 | if (ev.getAction() == MotionEvent.ACTION_DOWN) { 88 | View v = getCurrentFocus(); 89 | if (isShouldHideKeyboard(v, ev)) { 90 | hideKeyboard(v.getWindowToken()); 91 | } 92 | } 93 | return super.dispatchTouchEvent(ev); 94 | } 95 | 96 | // 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘 97 | private boolean isShouldHideKeyboard(View v, MotionEvent event) { 98 | if (v != null && (v instanceof EditText)) { 99 | int[] l = {0, 0}; 100 | v.getLocationInWindow(l); 101 | int left = l[0], 102 | top = l[1], 103 | bottom = top + v.getHeight(), 104 | right = left + v.getWidth(); 105 | return !(event.getX() > left && event.getX() < right 106 | && event.getY() > top && event.getY() < bottom); 107 | } 108 | return false; 109 | } 110 | 111 | // 获取InputMethodManager,隐藏软键盘 112 | private void hideKeyboard(IBinder token) { 113 | if (token != null) { 114 | InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 115 | im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS); 116 | } 117 | } 118 | */ 119 | } 120 | 121 | /** 122 | * 动态显示软键盘 123 | * 124 | * @param context 上下文 125 | * @param edit 输入框 126 | */ 127 | public static void showSoftInput(Context context, EditText edit) { 128 | edit.setFocusable(true); 129 | edit.setFocusableInTouchMode(true); 130 | edit.requestFocus(); 131 | InputMethodManager inputManager = (InputMethodManager) context 132 | .getSystemService(Context.INPUT_METHOD_SERVICE); 133 | inputManager.showSoftInput(edit, 0); 134 | } 135 | 136 | /** 137 | * 切换键盘显示与否状态 138 | * 139 | * @param context 上下文 140 | * @param edit 输入框 141 | */ 142 | public static void toggleSoftInput(Context context, EditText edit) { 143 | edit.setFocusable(true); 144 | edit.setFocusableInTouchMode(true); 145 | edit.requestFocus(); 146 | InputMethodManager inputManager = (InputMethodManager) context 147 | .getSystemService(Context.INPUT_METHOD_SERVICE); 148 | inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); 149 | } 150 | } -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/SPUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | *10 | * author: Blankj 11 | * blog : http://blankj.com 12 | * time : 2016/8/2 13 | * desc : SP相关工具类 14 | *15 | */ 16 | public class SPUtils { 17 | 18 | private SharedPreferences sp; 19 | private SharedPreferences.Editor editor; 20 | 21 | /** 22 | * SPUtils构造函数 23 | * 24 | * @param context 上下文 25 | * @param spName spName 26 | */ 27 | public SPUtils(Context context, String spName) { 28 | sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE); 29 | editor = sp.edit(); 30 | editor.apply(); 31 | } 32 | 33 | /** 34 | * SP中写入String类型value 35 | * 36 | * @param key 键 37 | * @param value 值 38 | */ 39 | public void putString(String key, String value) { 40 | editor.putString(key, value).apply(); 41 | } 42 | 43 | /** 44 | * SP中读取String 45 | * 46 | * @param key 键 47 | * @return 存在返回对应值,不存在返回默认值{@code null} 48 | */ 49 | public String getString(String key) { 50 | return getString(key, null); 51 | } 52 | 53 | /** 54 | * SP中读取String 55 | * 56 | * @param key 键 57 | * @param defaultValue 默认值 58 | * @return 存在返回对应值,不存在返回默认值{@code defaultValue} 59 | */ 60 | public String getString(String key, String defaultValue) { 61 | return sp.getString(key, defaultValue); 62 | } 63 | 64 | /** 65 | * SP中写入int类型value 66 | * 67 | * @param key 键 68 | * @param value 值 69 | */ 70 | public void putInt(String key, int value) { 71 | editor.putInt(key, value).apply(); 72 | } 73 | 74 | /** 75 | * SP中读取int 76 | * 77 | * @param key 键 78 | * @return 存在返回对应值,不存在返回默认值-1 79 | */ 80 | public int getInt(String key) { 81 | return getInt(key, -1); 82 | } 83 | 84 | /** 85 | * SP中读取int 86 | * 87 | * @param key 键 88 | * @param defaultValue 默认值 89 | * @return 存在返回对应值,不存在返回默认值{@code defaultValue} 90 | */ 91 | public int getInt(String key, int defaultValue) { 92 | return sp.getInt(key, defaultValue); 93 | } 94 | 95 | /** 96 | * SP中写入long类型value 97 | * 98 | * @param key 键 99 | * @param value 值 100 | */ 101 | public void putLong(String key, long value) { 102 | editor.putLong(key, value).apply(); 103 | } 104 | 105 | /** 106 | * SP中读取long 107 | * 108 | * @param key 键 109 | * @return 存在返回对应值,不存在返回默认值-1 110 | */ 111 | public long getLong(String key) { 112 | return getLong(key, -1L); 113 | } 114 | 115 | /** 116 | * SP中读取long 117 | * 118 | * @param key 键 119 | * @param defaultValue 默认值 120 | * @return 存在返回对应值,不存在返回默认值{@code defaultValue} 121 | */ 122 | public long getLong(String key, long defaultValue) { 123 | return sp.getLong(key, defaultValue); 124 | } 125 | 126 | /** 127 | * SP中写入float类型value 128 | * 129 | * @param key 键 130 | * @param value 值 131 | */ 132 | public void putFloat(String key, float value) { 133 | editor.putFloat(key, value).apply(); 134 | } 135 | 136 | /** 137 | * SP中读取float 138 | * 139 | * @param key 键 140 | * @return 存在返回对应值,不存在返回默认值-1 141 | */ 142 | public float getFloat(String key) { 143 | return getFloat(key, -1f); 144 | } 145 | 146 | /** 147 | * SP中读取float 148 | * 149 | * @param key 键 150 | * @param defaultValue 默认值 151 | * @return 存在返回对应值,不存在返回默认值{@code defaultValue} 152 | */ 153 | public float getFloat(String key, float defaultValue) { 154 | return sp.getFloat(key, defaultValue); 155 | } 156 | 157 | /** 158 | * SP中写入boolean类型value 159 | * 160 | * @param key 键 161 | * @param value 值 162 | */ 163 | public void putBoolean(String key, boolean value) { 164 | editor.putBoolean(key, value).apply(); 165 | } 166 | 167 | /** 168 | * SP中读取boolean 169 | * 170 | * @param key 键 171 | * @return 存在返回对应值,不存在返回默认值{@code false} 172 | */ 173 | public boolean getBoolean(String key) { 174 | return getBoolean(key, false); 175 | } 176 | 177 | /** 178 | * SP中读取boolean 179 | * 180 | * @param key 键 181 | * @param defaultValue 默认值 182 | * @return 存在返回对应值,不存在返回默认值{@code defaultValue} 183 | */ 184 | public boolean getBoolean(String key, boolean defaultValue) { 185 | return sp.getBoolean(key, defaultValue); 186 | } 187 | 188 | /** 189 | * 获取SP中所有键值对 190 | * 191 | * @return Map对象 192 | */ 193 | public Map
13 | * author: Blankj 14 | * blog : http://blankj.com 15 | * time : 2016/8/7 16 | * desc : 编码解码相关工具类 17 | *18 | */ 19 | public class EncodeUtils { 20 | 21 | private EncodeUtils() { 22 | throw new UnsupportedOperationException("u can't fuck me..."); 23 | } 24 | 25 | /** 26 | * URL编码 27 | *
若想自己指定字符集,可以使用{@link #urlEncode(String input, String charset)}方法
28 | * 29 | * @param input 要编码的字符 30 | * @return 编码为UTF-8的字符串 31 | */ 32 | public static String urlEncode(String input) { 33 | return urlEncode(input, "UTF-8"); 34 | } 35 | 36 | /** 37 | * URL编码 38 | *若系统不支持指定的编码字符集,则直接将input原样返回
39 | * 40 | * @param input 要编码的字符 41 | * @param charset 字符集 42 | * @return 编码为字符集的字符串 43 | */ 44 | public static String urlEncode(String input, String charset) { 45 | try { 46 | return URLEncoder.encode(input, charset); 47 | } catch (UnsupportedEncodingException e) { 48 | return input; 49 | } 50 | } 51 | 52 | /** 53 | * URL解码 54 | *若想自己指定字符集,可以使用 {@link #urlDecode(String input, String charset)}方法
55 | * 56 | * @param input 要解码的字符串 57 | * @return URL解码后的字符串 58 | */ 59 | public static String urlDecode(String input) { 60 | return urlDecode(input, "UTF-8"); 61 | } 62 | 63 | /** 64 | * URL解码 65 | *若系统不支持指定的解码字符集,则直接将input原样返回
66 | * 67 | * @param input 要解码的字符串 68 | * @param charset 字符集 69 | * @return URL解码为指定字符集的字符串 70 | */ 71 | public static String urlDecode(String input, String charset) { 72 | try { 73 | return URLDecoder.decode(input, charset); 74 | } catch (UnsupportedEncodingException e) { 75 | return input; 76 | } 77 | } 78 | 79 | /** 80 | * Base64编码 81 | * 82 | * @param input 要编码的字符串 83 | * @return Base64编码后的字符串 84 | */ 85 | public static byte[] base64Encode(String input) { 86 | return base64Encode(input.getBytes()); 87 | } 88 | 89 | /** 90 | * Base64编码 91 | * 92 | * @param input 要编码的字节数组 93 | * @return Base64编码后的字符串 94 | */ 95 | public static byte[] base64Encode(byte[] input) { 96 | return Base64.encode(input, Base64.NO_WRAP); 97 | } 98 | 99 | /** 100 | * Base64编码 101 | * 102 | * @param input 要编码的字节数组 103 | * @return Base64编码后的字符串 104 | */ 105 | public static String base64Encode2String(byte[] input) { 106 | return Base64.encodeToString(input, Base64.NO_WRAP); 107 | } 108 | 109 | /** 110 | * Base64解码 111 | * 112 | * @param input 要解码的字符串 113 | * @return Base64解码后的字符串 114 | */ 115 | public static byte[] base64Decode(String input) { 116 | return Base64.decode(input, Base64.NO_WRAP); 117 | } 118 | 119 | /** 120 | * Base64解码 121 | * 122 | * @param input 要解码的字符串 123 | * @return Base64解码后的字符串 124 | */ 125 | public static byte[] base64Decode(byte[] input) { 126 | return Base64.decode(input, Base64.NO_WRAP); 127 | } 128 | 129 | /** 130 | * Base64URL安全编码 131 | *将Base64中的URL非法字符�?,/=转为其他字符, 见RFC3548
132 | * 133 | * @param input 要Base64URL安全编码的字符串 134 | * @return Base64URL安全编码后的字符串 135 | */ 136 | public static byte[] base64UrlSafeEncode(String input) { 137 | return Base64.encode(input.getBytes(), Base64.URL_SAFE); 138 | } 139 | 140 | /** 141 | * Html编码 142 | * 143 | * @param input 要Html编码的字符串 144 | * @return Html编码后的字符串 145 | */ 146 | public static String htmlEncode(String input) { 147 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 148 | return Html.escapeHtml(input); 149 | } else { 150 | // 参照Html.escapeHtml()中代码 151 | StringBuilder out = new StringBuilder(); 152 | for (int i = 0, len = input.length(); i < len; i++) { 153 | char c = input.charAt(i); 154 | if (c == '<') { 155 | out.append("<"); 156 | } else if (c == '>') { 157 | out.append(">"); 158 | } else if (c == '&') { 159 | out.append("&"); 160 | } else if (c >= 0xD800 && c <= 0xDFFF) { 161 | if (c < 0xDC00 && i + 1 < len) { 162 | char d = input.charAt(i + 1); 163 | if (d >= 0xDC00 && d <= 0xDFFF) { 164 | i++; 165 | int codepoint = 0x010000 | (int) c - 0xD800 << 10 | (int) d - 0xDC00; 166 | out.append("").append(codepoint).append(";"); 167 | } 168 | } 169 | } else if (c > 0x7E || c < ' ') { 170 | out.append("").append((int) c).append(";"); 171 | } else if (c == ' ') { 172 | while (i + 1 < len && input.charAt(i + 1) == ' ') { 173 | out.append(" "); 174 | i++; 175 | } 176 | out.append(' '); 177 | } else { 178 | out.append(c); 179 | } 180 | } 181 | return out.toString(); 182 | } 183 | } 184 | 185 | /** 186 | * Html解码 187 | * 188 | * @param input 待解码的字符串 189 | * @return Html解码后的字符串 190 | */ 191 | public static String htmlDecode(String input) { 192 | return Html.fromHtml(input).toString(); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/SDCardUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.os.Environment; 4 | import android.os.StatFs; 5 | 6 | import java.io.File; 7 | 8 | import static com.blankj.utilcode.utils.ConstUtils.*; 9 | 10 | /** 11 | *12 | * author: Blankj 13 | * blog : http://blankj.com 14 | * time : 2016/8/11 15 | * desc : SD卡相关工具类 16 | *17 | */ 18 | public class SDCardUtils { 19 | 20 | private SDCardUtils() { 21 | throw new UnsupportedOperationException("u can't fuck me..."); 22 | } 23 | 24 | /** 25 | * 判断SD卡是否可用 26 | * 27 | * @return true : 可用
一般是/storage/emulated/0/
36 | * 37 | * @return SD卡路径 38 | */ 39 | public static String getSDCardPath() { 40 | return Environment.getExternalStorageDirectory().getPath() + File.separator; 41 | } 42 | 43 | /** 44 | * 获取SD卡Data路径 45 | * 46 | * @return Data路径 47 | */ 48 | public static String getDataPath() { 49 | return Environment.getDataDirectory().getPath(); 50 | 51 | } 52 | 53 | /** 54 | * 计算SD卡的剩余空间 55 | * 56 | * @param unit11 | * author: Blankj 12 | * blog : http://blankj.com 13 | * time : 2016/8/7 14 | * desc : Shell相关工具类 15 | *16 | */ 17 | public class ShellUtils { 18 | 19 | private ShellUtils() { 20 | throw new UnsupportedOperationException("u can't fuck me..."); 21 | } 22 | 23 | public static final String COMMAND_SU = "su"; 24 | public static final String COMMAND_SH = "sh"; 25 | public static final String COMMAND_EXIT = "exit\n"; 26 | public static final String COMMAND_LINE_END = "\n"; 27 | 28 | /** 29 | * 判断设备是否root 30 | * @return {@code true}: root
17 | * author: Blankj 18 | * blog : http://blankj.com 19 | * time : 2016/8/6 20 | * desc : EncryptUtils单元测试 21 | *22 | */ 23 | @RunWith(RobolectricTestRunner.class) 24 | @Config(manifest = Config.NONE) 25 | public class EncryptUtilsTest { 26 | 27 | String blankjMD2 = "15435017570D8A73449E25C4622E17A4"; 28 | String blankjMD5 = "AAC25CD336E01C8655F4EC7875445A60"; 29 | String blankjSHA1 = "C606ACCB1FEB669E19D080ADDDDBB8E6CDA5F43C"; 30 | String blankjSHA224 = "F4C5C0E8CF56CAC4D06DB6B523F67621859A9D79BDA4B2AC03097D5F"; 31 | String blankjSHA256 = "8BD80AE90DFBA112786367BEBDDEE60A638EF5B82682EDF8F3D3CA8E6BFEF648"; 32 | String blankjSHA384 = 33 | "BF831E5221FC108D6A72ACB888BA3EB0C030A5F01BA2F739856BE70681D86F992B85E0D461101C74BAEDA895BD422557"; 34 | String blankjSHA512 = 35 | "D59D31067F614ED3586F85A31FEFDB7F33096316DA26EBE0FF440B241C8560D96650F100D78C512560C976949EFA89CB5D5589DCF68C7FAADE98F03BCFEC2B45"; 36 | 37 | @Test 38 | public void testEncryptMD2() throws Exception { 39 | assertThat(encryptMD2ToString("blankj")).isEqualTo(blankjMD2); 40 | assertThat(encryptMD2ToString("blankj".getBytes())).isEqualTo(blankjMD2); 41 | assertThat(encryptMD2("blankj".getBytes())).isEqualTo(hexString2Bytes(blankjMD2)); 42 | } 43 | 44 | @Test 45 | public void testEncryptMD5() throws Exception { 46 | assertThat(encryptMD5ToString("blankj")).isEqualTo(blankjMD5); 47 | assertThat(encryptMD5ToString("blankj".getBytes())).isEqualTo(blankjMD5); 48 | assertThat(encryptMD5("blankj".getBytes())).isEqualTo(hexString2Bytes(blankjMD5)); 49 | } 50 | 51 | @Test 52 | public void testEncryptSHA1() throws Exception { 53 | assertThat(encryptSHA1ToString("blankj")).isEqualTo(blankjSHA1); 54 | assertThat(encryptSHA1ToString("blankj".getBytes())).isEqualTo(blankjSHA1); 55 | assertThat(encryptSHA1("blankj".getBytes())).isEqualTo(hexString2Bytes(blankjSHA1)); 56 | } 57 | 58 | @Test 59 | public void testEncryptSHA224() throws Exception { 60 | assertThat(encryptSHA224ToString("blankj")).isEqualTo(blankjSHA224); 61 | assertThat(encryptSHA224ToString("blankj".getBytes())).isEqualTo(blankjSHA224); 62 | assertThat(encryptSHA224("blankj".getBytes())).isEqualTo(hexString2Bytes(blankjSHA224)); 63 | } 64 | 65 | @Test 66 | public void testEncryptSHA256() throws Exception { 67 | assertThat(encryptSHA256ToString("blankj")).isEqualTo(blankjSHA256); 68 | assertThat(encryptSHA256ToString("blankj".getBytes())).isEqualTo(blankjSHA256); 69 | assertThat(encryptSHA256("blankj".getBytes())).isEqualTo(hexString2Bytes(blankjSHA256)); 70 | } 71 | 72 | @Test 73 | public void testEncryptSHA384() throws Exception { 74 | assertThat(encryptSHA384ToString("blankj")).isEqualTo(blankjSHA384); 75 | assertThat(encryptSHA384ToString("blankj".getBytes())).isEqualTo(blankjSHA384); 76 | assertThat(encryptSHA384("blankj".getBytes())).isEqualTo(hexString2Bytes(blankjSHA384)); 77 | } 78 | 79 | @Test 80 | public void testEncryptSHA512() throws Exception { 81 | assertThat(encryptSHA512ToString("blankj")).isEqualTo(blankjSHA512); 82 | assertThat(encryptSHA512ToString("blankj".getBytes())).isEqualTo(blankjSHA512); 83 | assertThat(encryptSHA512("blankj".getBytes())).isEqualTo(hexString2Bytes(blankjSHA512)); 84 | } 85 | 86 | String dataDES = "0008DB3345AB0223"; 87 | String keyDES = "6801020304050607"; 88 | String resDES = "1F7962581118F360"; 89 | byte[] bytesDataDES = hexString2Bytes(dataDES); 90 | byte[] bytesKeyDES = hexString2Bytes(keyDES); 91 | byte[] bytesResDES = hexString2Bytes(resDES); 92 | 93 | @Test 94 | public void testEncryptDES() throws Exception { 95 | assertThat(encryptDES(bytesDataDES, bytesKeyDES)).isEqualTo(bytesResDES); 96 | assertThat(encryptDES2HexString(bytesDataDES, bytesKeyDES)).isEqualTo(resDES); 97 | assertThat(encryptDES2Base64(bytesDataDES, bytesKeyDES)).isEqualTo(base64Encode 98 | (bytesResDES)); 99 | } 100 | 101 | @Test 102 | public void testDecryptDES() throws Exception { 103 | assertThat(decryptDES(bytesResDES, bytesKeyDES)).isEqualTo(bytesDataDES); 104 | assertThat(decryptHexStringDES(resDES, bytesKeyDES)).isEqualTo(bytesDataDES); 105 | assertThat(decryptBase64DES(base64Encode(bytesResDES), bytesKeyDES)).isEqualTo 106 | (bytesDataDES); 107 | } 108 | 109 | String data3DES = "1111111111111111"; 110 | String key3DES = "111111111111111111111111111111111111111111111111"; 111 | String res3DES = "F40379AB9E0EC533"; 112 | byte[] bytesDataDES3 = hexString2Bytes(data3DES); 113 | byte[] bytesKeyDES3 = hexString2Bytes(key3DES); 114 | byte[] bytesResDES3 = hexString2Bytes(res3DES); 115 | 116 | @Test 117 | public void testEncrypt3DES() throws Exception { 118 | assertThat(encrypt3DES(bytesDataDES3, bytesKeyDES3)).isEqualTo(bytesResDES3); 119 | assertThat(encrypt3DES2HexString(bytesDataDES3, bytesKeyDES3)).isEqualTo(res3DES); 120 | assertThat(encrypt3DES2Base64(bytesDataDES3, bytesKeyDES3)).isEqualTo(base64Encode 121 | (bytesResDES3)); 122 | } 123 | 124 | @Test 125 | public void testDecrypt3DES() throws Exception { 126 | assertThat(decrypt3DES(bytesResDES3, bytesKeyDES3)).isEqualTo(bytesDataDES3); 127 | assertThat(decryptHexString3DES(res3DES, bytesKeyDES3)).isEqualTo(bytesDataDES3); 128 | assertThat(decryptBase64_3DES(base64Encode(bytesResDES3), bytesKeyDES3)).isEqualTo 129 | (bytesDataDES3); 130 | } 131 | 132 | String dataAES = "11111111111111111111111111111111"; 133 | String keyAES = "11111111111111111111111111111111"; 134 | String resAES = "E56E26F5608B8D268F2556E198A0E01B"; 135 | byte[] bytesDataAES = hexString2Bytes(dataAES); 136 | byte[] bytesKeyAES = hexString2Bytes(keyAES); 137 | byte[] bytesResAES = hexString2Bytes(resAES); 138 | 139 | @Test 140 | public void testEncryptAES() throws Exception { 141 | assertThat(encryptAES(bytesDataAES, bytesKeyAES)).isEqualTo(bytesResAES); 142 | assertThat(encryptAES2HexString(bytesDataAES, bytesKeyAES)).isEqualTo(resAES); 143 | assertThat(encryptAES2Base64(bytesDataAES, bytesKeyAES)).isEqualTo(base64Encode 144 | (bytesResAES)); 145 | } 146 | 147 | @Test 148 | public void testDecryptAES() throws Exception { 149 | assertThat(decryptAES(bytesResAES, bytesKeyAES)).isEqualTo(bytesDataAES); 150 | assertThat(decryptHexStringAES(resAES, bytesKeyAES)).isEqualTo(bytesDataAES); 151 | assertThat(decryptBase64AES(base64Encode(bytesResAES), bytesKeyAES)).isEqualTo 152 | (bytesDataAES); 153 | } 154 | 155 | String path = TestUtils.BASEPATH + "encrypt" + TestUtils.SEP; 156 | String md5 = "7F138A09169B250E9DCB378140907378"; 157 | 158 | @Test 159 | public void testEncryptMD5File() throws Exception { 160 | assertThat(encryptMD5File2String(new File(path + "MD5.txt"))).isEqualTo(md5); 161 | } 162 | } -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/ScreenUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.app.Activity; 4 | import android.app.KeyguardManager; 5 | import android.content.Context; 6 | import android.content.pm.ActivityInfo; 7 | import android.graphics.Bitmap; 8 | import android.os.Build; 9 | import android.util.DisplayMetrics; 10 | import android.util.TypedValue; 11 | import android.view.View; 12 | import android.view.Window; 13 | import android.view.WindowManager; 14 | import android.view.WindowManager.LayoutParams; 15 | 16 | import java.lang.reflect.Method; 17 | 18 | /** 19 | *
20 | * author: Blankj 21 | * blog : http://blankj.com 22 | * time : 2016/8/2 23 | * desc : 屏幕相关工具类 24 | *25 | */ 26 | public class ScreenUtils { 27 | 28 | private ScreenUtils() { 29 | throw new UnsupportedOperationException("u can't fuck me..."); 30 | } 31 | 32 | /** 33 | * 获取屏幕的宽度px 34 | * 35 | * @param context 上下文 36 | * @return 屏幕宽px 37 | */ 38 | public static int getScreenWidth(Context context) { 39 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 40 | DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸 41 | windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高 42 | return outMetrics.widthPixels; 43 | } 44 | 45 | /** 46 | * 获取屏幕的高度px 47 | * 48 | * @param context 上下文 49 | * @return 屏幕高px 50 | */ 51 | public static int getScreenHeight(Context context) { 52 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 53 | DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸 54 | windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高 55 | return outMetrics.heightPixels; 56 | } 57 | 58 | /** 59 | * 设置透明状态栏(api大于19方可使用) 60 | *
可在Activity的onCreat()中调用
61 | *需在顶部控件布局中加入以下属性让内容出现在状态栏之下
62 | *android:clipToPadding="true"
63 | *android:fitsSystemWindows="true"
64 | * 65 | * @param activity activity 66 | */ 67 | public static void setTransparentStatusBar(Activity activity) { 68 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 69 | //透明状态栏 70 | activity.getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS); 71 | //透明导航栏 72 | activity.getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); 73 | } 74 | } 75 | 76 | /** 77 | * 隐藏状态栏 78 | *也就是设置全屏,一定要在setContentView之前调用,否则报错
79 | *此方法Activity可以继承AppCompatActivity
80 | *启动的时候状态栏会显示一下再隐藏,比如QQ的欢迎界面
81 | *在配置文件中Activity加属性android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
82 | *如加了以上配置Activity不能继承AppCompatActivity,会报错
83 | * 84 | * @param activity activity 85 | */ 86 | public static void hideStatusBar(Activity activity) { 87 | activity.requestWindowFeature(Window.FEATURE_NO_TITLE); 88 | activity.getWindow().setFlags(LayoutParams.FLAG_FULLSCREEN, 89 | LayoutParams.FLAG_FULLSCREEN); 90 | } 91 | 92 | /** 93 | * 获取状态栏高度 94 | * 95 | * @param context 上下文 96 | * @return 状态栏高度 97 | */ 98 | public static int getStatusBarHeight(Context context) { 99 | int result = 0; 100 | int resourceId = context.getResources() 101 | .getIdentifier("status_bar_height", "dimen", "android"); 102 | if (resourceId > 0) { 103 | result = context.getResources().getDimensionPixelSize(resourceId); 104 | } 105 | return result; 106 | } 107 | 108 | /** 109 | * 判断状态栏是否存在 110 | * 111 | * @param activity activity 112 | * @return {@code true}: 存在需添加权限 {@code
需添加权限 {@code
还有一种就是在Activity中加属性android:screenOrientation="landscape"
177 | *不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
178 | *设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
179 | *设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"(4.0以上必须带最后一个参数)时 180 | * 切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
181 | * 182 | * @param activity activity 183 | */ 184 | public static void setLandscape(Activity activity) { 185 | activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 186 | } 187 | 188 | /** 189 | * 获取当前屏幕截图,包含状态栏 190 | * 191 | * @param activity activity 192 | * @return Bitmap 193 | */ 194 | public static Bitmap captureWithStatusBar(Activity activity) { 195 | View view = activity.getWindow().getDecorView(); 196 | view.setDrawingCacheEnabled(true); 197 | view.buildDrawingCache(); 198 | Bitmap bmp = view.getDrawingCache(); 199 | int width = getScreenWidth(activity); 200 | int height = getScreenHeight(activity); 201 | Bitmap bp = Bitmap.createBitmap(bmp, 0, 0, width, height); 202 | view.destroyDrawingCache(); 203 | return bp; 204 | } 205 | 206 | /** 207 | * 获取当前屏幕截图,不包含状态栏 208 | *需要用到上面获取状态栏高度getStatusBarHeight的方法
209 | * 210 | * @param activity activity 211 | * @return Bitmap 212 | */ 213 | public static Bitmap captureWithoutStatusBar(Activity activity) { 214 | View view = activity.getWindow().getDecorView(); 215 | view.setDrawingCacheEnabled(true); 216 | view.buildDrawingCache(); 217 | Bitmap bmp = view.getDrawingCache(); 218 | int statusBarHeight = getStatusBarHeight(activity); 219 | int width = getScreenWidth(activity); 220 | int height = getScreenHeight(activity); 221 | Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight); 222 | view.destroyDrawingCache(); 223 | return bp; 224 | } 225 | 226 | /** 227 | * 判断是否锁屏 228 | * 229 | * @param context 上下文 230 | * @return {@code true}: 是24 | * author: Blankj 25 | * blog : http://blankj.com 26 | * time : 2016/8/27 27 | * desc : 压缩相关工具类 28 | *29 | */ 30 | public class ZipUtils { 31 | 32 | private ZipUtils() { 33 | throw new UnsupportedOperationException("u can't fuck me..."); 34 | } 35 | 36 | /** 37 | * 批量压缩文件 38 | * 39 | * @param resFileList 要压缩的文件(夹)列表 40 | * @param zipFile 生成的压缩文件 41 | * @throws IOException 当压缩过程出错时抛出 42 | */ 43 | public static void zipFiles(Collection
11 | * author: Blankj 12 | * blog : http://blankj.com 13 | * time : 2016/8/2 14 | * desc : 网络相关工具类 15 | *16 | */ 17 | public class NetworkUtils { 18 | 19 | private NetworkUtils() { 20 | throw new UnsupportedOperationException("u can't fuck me..."); 21 | } 22 | 23 | public static final int NETWORK_WIFI = 1; // wifi network 24 | public static final int NETWORK_4G = 4; // "4G" networks 25 | public static final int NETWORK_3G = 3; // "3G" networks 26 | public static final int NETWORK_2G = 2; // "2G" networks 27 | public static final int NETWORK_UNKNOWN = 5; // unknown network 28 | public static final int NETWORK_NO = -1; // no network 29 | 30 | private static final int NETWORK_TYPE_GSM = 16; 31 | private static final int NETWORK_TYPE_TD_SCDMA = 17; 32 | private static final int NETWORK_TYPE_IWLAN = 18; 33 | 34 | /** 35 | * 打开网络设置界面 36 | *
3.0以下打开设置界面
37 | * 38 | * @param context 上下文 39 | */ 40 | public static void openWirelessSettings(Context context) { 41 | if (android.os.Build.VERSION.SDK_INT > 10) { 42 | context.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); 43 | } else { 44 | context.startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS)); 45 | } 46 | } 47 | 48 | /** 49 | * 获取活动网络信息 50 | * 51 | * @param context 上下文 52 | * @return NetworkInfo 53 | */ 54 | private static NetworkInfo getActiveNetworkInfo(Context context) { 55 | ConnectivityManager cm = (ConnectivityManager) context 56 | .getSystemService(Context.CONNECTIVITY_SERVICE); 57 | return cm.getActiveNetworkInfo(); 58 | } 59 | 60 | /** 61 | * 判断网络是否可用 62 | *需添加权限 {@code
需添加权限 {@code
需添加权限 {@code
需添加权限 {@code
如中国联通、中国移动、中国电信
112 | * 113 | * @param context 上下文 114 | * @return 移动网络运营商名称 115 | */ 116 | public static String getNetworkOperatorName(Context context) { 117 | TelephonyManager tm = (TelephonyManager) context 118 | .getSystemService(Context.TELEPHONY_SERVICE); 119 | return tm != null ? tm.getNetworkOperatorName() : null; 120 | } 121 | 122 | /** 123 | * 获取移动终端类型 124 | * 125 | * @param context 上下文 126 | * @return 手机制式 127 | *需添加权限 {@code
依赖上面的方法
214 | * 215 | * @param context 上下文 216 | * @return 网络类型名称 217 | *17 | * author: Blankj 18 | * blog : http://blankj.com 19 | * time : 2016/8/25 20 | * desc : 线程池相关工具类 21 | *22 | */ 23 | public class ThreadPoolUtils { 24 | 25 | public enum Type { 26 | FixedThread, 27 | CachedThread, 28 | SingleThread, 29 | } 30 | 31 | private ExecutorService exec; 32 | private ScheduledExecutorService scheduleExec; 33 | 34 | /** 35 | * ThreadPoolUtils构造函数 36 | * 37 | * @param type 线程池类型 38 | * @param corePoolSize 只对Fixed和Scheduled线程池起效 39 | */ 40 | public ThreadPoolUtils(Type type, int corePoolSize) { 41 | // 构造有定时功能的线程池 42 | // ThreadPoolExecutor(corePoolSize, Integer.MAX_VALUE, 10L, TimeUnit.MILLISECONDS, new BlockingQueue
该命令可能在新的线程、已入池的线程或者正调用的线程中执行,这由 Executor 实现决定。
70 | * 71 | * @param command 命令 72 | */ 73 | public void execute(Runnable command) { 74 | exec.execute(command); 75 | } 76 | 77 | /** 78 | * 在未来某个时间执行给定的命令链表 79 | *该命令可能在新的线程、已入池的线程或者正调用的线程中执行,这由 Executor 实现决定。
80 | * 81 | * @param commands 命令链表 82 | */ 83 | public void execute(List启动一次顺序关闭,执行以前提交的任务,但不接受新任务。 92 | * 如果已经关闭,则调用没有作用。
93 | */ 94 | public void shutDown() { 95 | exec.shutdown(); 96 | } 97 | 98 | /** 99 | * 试图停止所有正在执行的活动任务 100 | *试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
101 | *无法保证能够停止正在处理的活动执行任务,但是会尽力尝试。
102 | * 103 | * @return 等待执行的任务的列表 104 | */ 105 | public List注意,除非首先调用 shutdown 或 shutdownNow,否则 isTerminated 永不为 true。
121 | * 122 | * @return {@code true}: 是无论哪一个首先发生之后,都将导致阻塞,直到所有任务完成执行。
132 | * 133 | * @param timeout 最长等待时间 134 | * @param unit 时间单位 135 | * @return {@code true}: 请求成功如果想立即阻塞任务的等待,则可以使用{@code result = exec.submit(aCallable).get();}形式的构造。
144 | * 145 | * @param task 任务 146 | * @return 表示任务等待完成的Future, 该Future的{@code get}方法在成功完成时将会返回该任务的结果。 147 | */ 148 | public当所有任务完成时,返回保持任务状态和结果的Future列表。 176 | * 返回列表的所有元素的{@link Future#isDone}为{@code true}。 177 | * 注意,可以正常地或通过抛出异常来终止已完成任务。 178 | * 如果正在进行此操作时修改了给定的 collection,则此方法的结果是不确定的。
179 | * 180 | * @param tasks 任务集合 181 | * @return 表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同,每个任务都已完成。 182 | * @throws InterruptedException 如果等待时发生中断,在这种情况下取消尚未完成的任务。 183 | */ 184 | public当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的Future列表。 191 | * 返回列表的所有元素的{@link Future#isDone}为{@code true}。 192 | * 一旦返回后,即取消尚未完成的任务。 193 | * 注意,可以正常地或通过抛出异常来终止已完成任务。 194 | * 如果此操作正在进行时修改了给定的 collection,则此方法的结果是不确定的。
195 | * 196 | * @param tasks 任务集合 197 | * @param timeout 最长等待时间 198 | * @param unit 时间单位 199 | * @return 表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同。如果操作未超时,则已完成所有任务。如果确实超时了,则某些任务尚未完成。 200 | * @throws InterruptedException 如果等待时发生中断,在这种情况下取消尚未完成的任务 201 | */ 202 | public如果某个任务已成功完成(也就是未抛出异常),则返回其结果。 210 | * 一旦正常或异常返回后,则取消尚未完成的任务。 211 | * 如果此操作正在进行时修改了给定的collection,则此方法的结果是不确定的。
212 | * 213 | * @param tasks 任务集合 214 | * @return 某个任务返回的结果 215 | * @throws InterruptedException 如果等待时发生中断 216 | * @throws ExecutionException 如果没有任务成功完成 217 | */ 218 | public如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果。 225 | * 一旦正常或异常返回后,则取消尚未完成的任务。 226 | * 如果此操作正在进行时修改了给定的collection,则此方法的结果是不确定的。
227 | * 228 | * @param tasks 任务集合 229 | * @param timeout 最长等待时间 230 | * @param unit 时间单位 231 | * @return 某个任务返回的结果 232 | * @throws InterruptedException 如果等待时发生中断 233 | * @throws ExecutionException 如果没有任务成功完成 234 | * @throws TimeoutException 如果在所有任务成功完成之前给定的超时期满 235 | */ 236 | public19 | * author: Blankj 20 | * blog : http://blankj.com 21 | * time : 2016/8/2 22 | * desc : App相关工具类 23 | *24 | */ 25 | public class AppUtils { 26 | 27 | private AppUtils() { 28 | throw new UnsupportedOperationException("u can't fuck me..."); 29 | } 30 | 31 | /** 32 | * 安装App 33 | *
根据路径安装App
34 | * 35 | * @param context 上下文 36 | * @param filePath 文件路径 37 | */ 38 | public static void installApp(Context context, String filePath) { 39 | installApp(context, new File(filePath)); 40 | } 41 | 42 | /** 43 | * 安装App 44 | *根据文件安装App
45 | * 46 | * @param context 上下文 47 | * @param file 文件 48 | */ 49 | public static void installApp(Context context, File file) { 50 | Intent intent = new Intent(Intent.ACTION_VIEW); 51 | intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); 52 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 53 | context.startActivity(intent); 54 | } 55 | 56 | /** 57 | * 卸载指定包名的App 58 | * 59 | * @param context 上下文 60 | * @param packageName 包名 61 | */ 62 | public void uninstallApp(Context context, String packageName) { 63 | Intent intent = new Intent(Intent.ACTION_DELETE); 64 | intent.setData(Uri.parse("package:" + packageName)); 65 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 66 | context.startActivity(intent); 67 | } 68 | 69 | /** 70 | * 封装App信息的Bean类 71 | */ 72 | public static class AppInfo { 73 | 74 | private String name; 75 | private Drawable icon; 76 | private String packageName; 77 | private String packagePath; 78 | private String versionName; 79 | private int versionCode; 80 | private boolean isSD; 81 | private boolean isUser; 82 | 83 | public Drawable getIcon() { 84 | return icon; 85 | } 86 | 87 | public void setIcon(Drawable icon) { 88 | this.icon = icon; 89 | } 90 | 91 | public boolean isSD() { 92 | return isSD; 93 | } 94 | 95 | public void setSD(boolean SD) { 96 | isSD = SD; 97 | } 98 | 99 | public boolean isUser() { 100 | return isUser; 101 | } 102 | 103 | public void setUser(boolean user) { 104 | isUser = user; 105 | } 106 | 107 | public String getName() { 108 | return name; 109 | } 110 | 111 | public void setName(String name) { 112 | this.name = name; 113 | } 114 | 115 | public String getPackageName() { 116 | return packageName; 117 | } 118 | 119 | public void setPackageName(String packagName) { 120 | this.packageName = packagName; 121 | } 122 | 123 | public String getPackagePath() { 124 | return packagePath; 125 | } 126 | 127 | public void setPackagePath(String packagePath) { 128 | this.packagePath = packagePath; 129 | } 130 | 131 | public int getVersionCode() { 132 | return versionCode; 133 | } 134 | 135 | public void setVersionCode(int versionCode) { 136 | this.versionCode = versionCode; 137 | } 138 | 139 | public String getVersionName() { 140 | return versionName; 141 | } 142 | 143 | public void setVersionName(String versionName) { 144 | this.versionName = versionName; 145 | } 146 | 147 | /** 148 | * @param name 名称 149 | * @param icon 图标 150 | * @param packageName 包名 151 | * @param packagePath 包路径 152 | * @param versionName 版本号 153 | * @param versionCode 版本Code 154 | * @param isSD 是否安装在SD卡 155 | * @param isUser 是否是用户程序 156 | */ 157 | public AppInfo(String name, Drawable icon, String packageName, String packagePath, 158 | String versionName, int versionCode, boolean isSD, boolean isUser) { 159 | this.setName(name); 160 | this.setIcon(icon); 161 | this.setPackageName(packageName); 162 | this.setPackagePath(packagePath); 163 | this.setVersionName(versionName); 164 | this.setVersionCode(versionCode); 165 | this.setSD(isSD); 166 | this.setUser(isUser); 167 | } 168 | 169 | // @Override 170 | // public String toString() { 171 | // return getName() + "\n" 172 | // + getIcon() + "\n" 173 | // + getPackageName() + "\n" 174 | // + getPackagePath() + "\n" 175 | // + getVersionName() + "\n" 176 | // + getVersionCode() + "\n" 177 | // + isSD() + "\n" 178 | // + isUser() + "\n"; 179 | // } 180 | } 181 | 182 | /** 183 | * 获取当前App信息 184 | *AppInfo(名称,图标,包名,版本号,版本Code,是否安装在SD卡,是否是用户程序)
185 | * 186 | * @param context 上下文 187 | * @return 当前应用的AppInfo 188 | */ 189 | public static AppInfo getAppInfo(Context context) { 190 | PackageManager pm = context.getPackageManager(); 191 | PackageInfo pi = null; 192 | try { 193 | pi = pm.getPackageInfo(context.getApplicationContext().getPackageName(), 0); 194 | } catch (PackageManager.NameNotFoundException e) { 195 | e.printStackTrace(); 196 | } 197 | return pi != null ? getBean(pm, pi) : null; 198 | } 199 | 200 | /** 201 | * 得到AppInfo的Bean 202 | * 203 | * @param pm 包的管理 204 | * @param pi 包的信息 205 | * @return AppInfo类 206 | */ 207 | private static AppInfo getBean(PackageManager pm, PackageInfo pi) { 208 | ApplicationInfo ai = pi.applicationInfo; 209 | String name = ai.loadLabel(pm).toString(); 210 | Drawable icon = ai.loadIcon(pm); 211 | String packageName = pi.packageName; 212 | String packagePath = ai.sourceDir; 213 | String versionName = pi.versionName; 214 | int versionCode = pi.versionCode; 215 | boolean isSD = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != ApplicationInfo.FLAG_SYSTEM; 216 | boolean isUser = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != ApplicationInfo.FLAG_SYSTEM; 217 | return new AppInfo(name, icon, packageName, packagePath, versionName, versionCode, isSD, isUser); 218 | } 219 | 220 | /** 221 | * 获取所有已安装App信息 222 | *{@link #getBean(PackageManager, PackageInfo)}(名称,图标,包名,包路径,版本号,版本Code,是否安装在SD卡,是否是用户程序)
223 | *依赖上面的getBean方法
224 | * 225 | * @param context 上下文 226 | * @return 所有已安装的AppInfo列表 227 | */ 228 | public static List需添加权限 {@code
并且必须是系统应用该方法才有效
309 | * 310 | * @param context 上下文 311 | * @return {@code true}: 后台44 | * author: Blankj 45 | * blog : http://blankj.com 46 | * time : 2016/8/19 47 | * desc : FileUtils单元测试 48 | *49 | */ 50 | public class FileUtilsTest { 51 | 52 | 53 | String path = BASEPATH + "file" + SEP; 54 | 55 | @Test 56 | public void testGetFileByPath() throws Exception { 57 | System.out.println(new byte[0].length); 58 | assertThat(getFileByPath(" ")).isNull(); 59 | assertThat(getFileByPath("c:")).isNotNull(); 60 | } 61 | 62 | @Test 63 | public void testIsFileExists() throws Exception { 64 | assertThat(isFileExists(path + "UTF8.txt")).isTrue(); 65 | assertThat(isFileExists(path + "UTF8")).isFalse(); 66 | } 67 | 68 | @Test 69 | public void testIsDir() throws Exception { 70 | assertThat(isDir(path + "UTF8.txt")).isFalse(); 71 | assertThat(isDir(path)).isTrue(); 72 | } 73 | 74 | @Test 75 | public void testIsFile() throws Exception { 76 | assertThat(isFile(path + "UTF8.txt")).isTrue(); 77 | assertThat(isFile(path)).isFalse(); 78 | } 79 | 80 | @Test 81 | public void testCreateOrExistsDir() throws Exception { 82 | assertThat(createOrExistsDir(path + "new Dir")).isTrue(); 83 | assertThat(createOrExistsDir(path)).isTrue(); 84 | } 85 | 86 | @Test 87 | public void testCreateOrExistsFile() throws Exception { 88 | assertThat(createOrExistsFile(path + "new File")).isTrue(); 89 | assertThat(createOrExistsFile(path)).isFalse(); 90 | } 91 | 92 | @Test 93 | public void testCreateFileByDeleteOldFile() throws Exception { 94 | assertThat(createFileByDeleteOldFile(path + "new File")).isTrue(); 95 | assertThat(createFileByDeleteOldFile(path)).isFalse(); 96 | } 97 | 98 | String path1 = BASEPATH + "file1" + SEP; 99 | 100 | @Test 101 | public void testCopyDir() throws Exception { 102 | assertThat(copyDir(path, path)).isFalse(); 103 | assertThat(copyDir(path, path + "new Dir")).isFalse(); 104 | assertThat(copyDir(path, path1)).isTrue(); 105 | } 106 | 107 | @Test 108 | public void testCopyFile() throws Exception { 109 | assertThat(copyFile(path + "GBK.txt", path + "GBK.txt")).isFalse(); 110 | assertThat(copyFile(path + "GBK.txt", path + "new Dir" + SEP + "GBK.txt")).isTrue(); 111 | assertThat(copyFile(path + "GBK.txt", path1 + "GBK.txt")).isTrue(); 112 | } 113 | 114 | @Test 115 | public void testMoveDir() throws Exception { 116 | assertThat(moveDir(path, path)).isFalse(); 117 | assertThat(moveDir(path, path + "new Dir")).isFalse(); 118 | assertThat(moveDir(path, path1)).isTrue(); 119 | assertThat(moveDir(path1, path)).isTrue(); 120 | } 121 | 122 | @Test 123 | public void testMoveFile() throws Exception { 124 | assertThat(moveFile(path + "GBK.txt", path + "GBK.txt")).isFalse(); 125 | assertThat(moveFile(path + "GBK.txt", path1 + "GBK.txt")).isTrue(); 126 | assertThat(moveFile(path1 + "GBK.txt", path + "GBK.txt")).isTrue(); 127 | } 128 | 129 | @Test 130 | public void testDeleteDir() throws Exception { 131 | assertThat(deleteDir(path + "GBK.txt")).isFalse(); 132 | assertThat(deleteDir(path + "del")).isTrue(); 133 | } 134 | 135 | @Test 136 | public void testDeleteFile() throws Exception { 137 | assertThat(deleteFile(path)).isFalse(); 138 | assertThat(deleteFile(path + "GBK1.txt")).isTrue(); 139 | assertThat(deleteFile(path + "del.txt")).isTrue(); 140 | } 141 | 142 | @Test 143 | public void testListFilesInDir() throws Exception { 144 | System.out.println(listFilesInDir(path, false).toString()); 145 | System.out.println(listFilesInDir(path, true).toString()); 146 | } 147 | 148 | FilenameFilter filter = new FilenameFilter() { 149 | public boolean accept(File dir, String name) { 150 | return name.endsWith("k.txt"); 151 | } 152 | }; 153 | 154 | @Test 155 | public void testListFilesInDirWithFiltere() throws Exception { 156 | System.out.println(listFilesInDirWithFilter(path, "k.txt", false).toString()); 157 | System.out.println(listFilesInDirWithFilter(path, "k.txt", true).toString()); 158 | System.out.println(listFilesInDirWithFilter(path, filter, false).toString()); 159 | System.out.println(listFilesInDirWithFilter(path, filter, true).toString()); 160 | } 161 | 162 | @Test 163 | public void testSearchFile() throws Exception { 164 | System.out.println(searchFileInDir(path, "GBK.txt").toString()); 165 | System.out.println(searchFileInDir(path, "child").toString()); 166 | } 167 | 168 | @Test 169 | public void testWriteFileFromIS() throws Exception { 170 | assertThat(writeFileFromIS(path + "NEW.txt", new FileInputStream(path + "UTF8.txt"), false)) 171 | .isTrue(); 172 | assertThat(writeFileFromIS(path + "NEW.txt", new FileInputStream(path + "UTF8.txt"), true)) 173 | .isTrue(); 174 | } 175 | 176 | @Test 177 | public void testWriteFileFromString() throws Exception { 178 | assertThat(writeFileFromString(path + "NEW.txt", "这是新的", false)).isTrue(); 179 | assertThat(writeFileFromString(path + "NEW.txt", "\r\n这是追加的", true)).isTrue(); 180 | } 181 | 182 | @Test 183 | public void testGetFileCharsetSimple() throws Exception { 184 | assertThat(getFileCharsetSimple(path + "GBK.txt")).isEqualTo("GBK"); 185 | assertThat(getFileCharsetSimple(path + "Unicode.txt")).isEqualTo("Unicode"); 186 | assertThat(getFileCharsetSimple(path + "UTF8.txt")).isEqualTo("UTF-8"); 187 | assertThat(getFileCharsetSimple(path + "UTF16BE.txt")).isEqualTo("UTF-16BE"); 188 | } 189 | 190 | @Test 191 | public void testGetFileLines() throws Exception { 192 | assertThat(getFileLines(path + "UTF8.txt")).isEqualTo(7); 193 | } 194 | 195 | @Test 196 | public void testReadFile2List() throws Exception { 197 | System.out.println(readFile2List(path + "UTF8.txt", "").toString()); 198 | System.out.println(readFile2List(path + "UTF8.txt", "UTF-8").toString()); 199 | System.out.println(readFile2List(path + "UTF8.txt", 2, 5, "UTF-8").toString()); 200 | System.out.println(readFile2List(path + "UTF8.txt", "GBK").toString()); 201 | } 202 | 203 | @Test 204 | public void testReadFile2String() throws Exception { 205 | System.out.println(readFile2String(path + "UTF8.txt", "")); 206 | System.out.println(readFile2String(path + "UTF8.txt", "UTF-8")); 207 | System.out.println(readFile2String(path + "UTF8.txt", "GBK")); 208 | } 209 | 210 | 211 | @Test 212 | public void testReadFile2Bytes() throws Exception { 213 | System.out.println(new String(readFile2Bytes(path + "UTF8.txt")) ); 214 | } 215 | 216 | @Test 217 | public void testByte2Unit() throws Exception { 218 | assertThat(byte2Size(ConstUtils.GB, ConstUtils.MemoryUnit.MB) - 1024).isWithin(0.001); 219 | } 220 | 221 | @Test 222 | public void testGetFileSize() throws Exception { 223 | assertThat(getFileSize(path + "UTF8.txt", ConstUtils.MemoryUnit.BYTE) - 25).isWithin(0.001); 224 | } 225 | 226 | @Test 227 | public void testGetDirName() throws Exception { 228 | assertThat(getDirName(new File(path + "UTF8.txt"))).isEqualTo(path); 229 | assertThat(getDirName(path + "UTF8.txt")).isEqualTo(path); 230 | } 231 | 232 | @Test 233 | public void testGetFileName() throws Exception { 234 | assertThat(getFileName(new File(path + "UTF8.txt"))).isEqualTo("UTF8.txt"); 235 | assertThat(getFileName(path + "UTF8.txt")).isEqualTo("UTF8.txt"); 236 | } 237 | 238 | @Test 239 | public void testGetFileNameNoExtension() throws Exception { 240 | assertThat(getFileNameNoExtension(new File(path + "UTF8.txt"))).isEqualTo("UTF8"); 241 | assertThat(getFileNameNoExtension(path + "UTF8.txt")).isEqualTo("UTF8"); 242 | } 243 | 244 | @Test 245 | public void testGetFileExtension() throws Exception { 246 | assertThat(getFileExtension(new File(path + "UTF8.txt"))).isEqualTo(".txt"); 247 | assertThat(getFileExtension(path + "UTF8.txt")).isEqualTo(".txt"); 248 | } 249 | } -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/ConvertUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapFactory; 7 | import android.graphics.drawable.BitmapDrawable; 8 | import android.graphics.drawable.Drawable; 9 | 10 | import java.io.ByteArrayInputStream; 11 | import java.io.ByteArrayOutputStream; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.OutputStream; 15 | import java.io.UnsupportedEncodingException; 16 | 17 | /** 18 | *
19 | * author: Blankj 20 | * blog : http://blankj.com 21 | * time : 2016/8/13 22 | * desc : 转换相关工具类 23 | *24 | */ 25 | public class ConvertUtils { 26 | 27 | static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 28 | 29 | /** 30 | * byteArr转hexString 31 | *
例如:
32 | * bytes2HexString(new byte[] { 0, (byte) 0xa8 }) returns 00A8 33 | * 34 | * @param bytes byte数组 35 | * @return 16进制大写字符串 36 | */ 37 | public static String bytes2HexString(byte[] bytes) { 38 | char[] res = new char[bytes.length << 1]; 39 | for (int i = 0, j = 0; i < bytes.length; i++) { 40 | res[j++] = hexDigits[bytes[i] >>> 4 & 0x0f]; 41 | res[j++] = hexDigits[bytes[i] & 0x0f]; 42 | } 43 | return new String(res); 44 | } 45 | 46 | /** 47 | * hexString转byteArr 48 | *例如:
49 | * hexString2Bytes("00A8") returns { 0, (byte) 0xA8 } 50 | * 51 | * @param hexString 十六进制字符串 52 | * @return 字节数组 53 | */ 54 | public static byte[] hexString2Bytes(String hexString) { 55 | int len = hexString.length(); 56 | if (len % 2 != 0) { 57 | throw new IllegalArgumentException("长度不是偶数"); 58 | } 59 | char[] hexBytes = hexString.toUpperCase().toCharArray(); 60 | byte[] res = new byte[len >>> 1]; 61 | for (int i = 0; i < len; i += 2) { 62 | res[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1])); 63 | } 64 | return res; 65 | } 66 | 67 | /** 68 | * hexChar转int 69 | * 70 | * @param hexChar hex单个字节 71 | * @return 0..15 72 | */ 73 | private static int hex2Dec(char hexChar) { 74 | if (hexChar >= '0' && hexChar <= '9') { 75 | return hexChar - '0'; 76 | } else if (hexChar >= 'A' && hexChar <= 'F') { 77 | return hexChar - 'A' + 10; 78 | } else { 79 | throw new IllegalArgumentException(); 80 | } 81 | } 82 | 83 | /** 84 | * charArr转byteArr 85 | * 86 | * @param chars 字符数组 87 | * @return 字节数组 88 | */ 89 | public static byte[] chars2Bytes(char[] chars) { 90 | int len = chars.length; 91 | byte[] bytes = new byte[len]; 92 | for (int i = 0; i < len; i++) { 93 | bytes[i] = (byte) (chars[i]); 94 | } 95 | return bytes; 96 | } 97 | 98 | /** 99 | * byteArr转charArr 100 | * 101 | * @param bytes 字节数组 102 | * @return 字符数组 103 | */ 104 | public static char[] bytes2Chars(byte[] bytes) { 105 | int len = bytes.length; 106 | char[] chars = new char[len]; 107 | for (int i = 0; i < len; i++) { 108 | chars[i] = (char) (bytes[i] & 0xff); 109 | } 110 | return chars; 111 | } 112 | 113 | /** 114 | * inputStream转outputStream 115 | * 116 | * @param is 输入流 117 | * @return outputStream子类 118 | */ 119 | public static ByteArrayOutputStream input2OutputStream(InputStream is) { 120 | if (is == null) return null; 121 | try { 122 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 123 | byte[] b = new byte[ConstUtils.KB]; 124 | int len; 125 | while ((len = is.read(b)) != -1) { 126 | os.write(b, 0, len); 127 | } 128 | return os; 129 | } catch (IOException e) { 130 | e.printStackTrace(); 131 | return null; 132 | } finally { 133 | FileUtils.closeIO(is); 134 | } 135 | } 136 | 137 | /** 138 | * outputStream转inputStream 139 | * 140 | * @param out 输出流 141 | * @return inputStream子类 142 | */ 143 | public ByteArrayInputStream output2InputStream(OutputStream out) { 144 | if (out == null) return null; 145 | return new ByteArrayInputStream(((ByteArrayOutputStream) out).toByteArray()); 146 | } 147 | 148 | /** 149 | * inputStream转byteArr 150 | * 151 | * @param is 输入流 152 | * @return 字节数组 153 | */ 154 | public static byte[] inputStream2Bytes(InputStream is) { 155 | return input2OutputStream(is).toByteArray(); 156 | } 157 | 158 | /** 159 | * byteArr转inputStream 160 | * 161 | * @param bytes 字节数组 162 | * @return 输入流 163 | */ 164 | public static InputStream bytes2InputStream(byte[] bytes) { 165 | return new ByteArrayInputStream(bytes); 166 | } 167 | 168 | /** 169 | * outputStream转byteArr 170 | * 171 | * @param out 输出流 172 | * @return 字节数组 173 | */ 174 | public static byte[] outputStream2Bytes(OutputStream out) { 175 | if (out == null) return null; 176 | return ((ByteArrayOutputStream) out).toByteArray(); 177 | } 178 | 179 | /** 180 | * outputStream转byteArr 181 | * 182 | * @param bytes 字节数组 183 | * @return 字节数组 184 | */ 185 | public static OutputStream bytes2OutputStream(byte[] bytes) { 186 | ByteArrayOutputStream os = null; 187 | try { 188 | os = new ByteArrayOutputStream(); 189 | os.write(bytes); 190 | return os; 191 | } catch (IOException e) { 192 | e.printStackTrace(); 193 | return null; 194 | } finally { 195 | FileUtils.closeIO(os); 196 | } 197 | } 198 | 199 | /** 200 | * inputStream转string按编码 201 | * 202 | * @param is 输入流 203 | * @param charsetName 编码格式 204 | * @return 字符串 205 | */ 206 | public static String inputStream2String(InputStream is, String charsetName) { 207 | if (is == null || StringUtils.isSpace(charsetName)) return null; 208 | try { 209 | return new String(inputStream2Bytes(is), charsetName); 210 | } catch (UnsupportedEncodingException e) { 211 | e.printStackTrace(); 212 | return null; 213 | } 214 | } 215 | 216 | /** 217 | * string转inputStream按编码 218 | * 219 | * @param string 字符串 220 | * @param charsetName 编码格式 221 | * @return 输入流 222 | */ 223 | public static InputStream string2InputStream(String string, String charsetName) { 224 | if (string == null || StringUtils.isSpace(charsetName)) return null; 225 | try { 226 | return new ByteArrayInputStream(string.getBytes(charsetName)); 227 | } catch (UnsupportedEncodingException e) { 228 | e.printStackTrace(); 229 | return null; 230 | } 231 | } 232 | 233 | /** 234 | * outputStream转string按编码 235 | * 236 | * @param out 输出流 237 | * @param charsetName 编码格式 238 | * @return 字符串 239 | */ 240 | public static String outputStream2String(OutputStream out, String charsetName) { 241 | if (out == null) return null; 242 | try { 243 | return new String(outputStream2Bytes(out), charsetName); 244 | } catch (UnsupportedEncodingException e) { 245 | e.printStackTrace(); 246 | return null; 247 | } 248 | } 249 | 250 | /** 251 | * string转outputStream按编码 252 | * 253 | * @param string 字符串 254 | * @param charsetName 编码格式 255 | * @return 输入流 256 | */ 257 | public static OutputStream string2OutputStream(String string, String charsetName) { 258 | if (string == null || StringUtils.isSpace(charsetName)) return null; 259 | try { 260 | return bytes2OutputStream(string.getBytes(charsetName)); 261 | } catch (UnsupportedEncodingException e) { 262 | e.printStackTrace(); 263 | return null; 264 | } 265 | } 266 | 267 | /** 268 | * bitmap转byteArr 269 | * 270 | * @param bitmap bitmap对象 271 | * @param format 格式 272 | * @return 字节数组 273 | */ 274 | public static byte[] bitmap2Bytes(Bitmap bitmap, Bitmap.CompressFormat format) { 275 | if (bitmap == null) return null; 276 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 277 | bitmap.compress(format, 100, baos); 278 | return baos.toByteArray(); 279 | } 280 | 281 | /** 282 | * byteArr转bitmap 283 | * 284 | * @param bytes 字节数组 285 | * @return bitmap对象 286 | */ 287 | public static Bitmap bytes2Bitmap(byte[] bytes) { 288 | return (bytes == null || bytes.length == 0) ? null : BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 289 | } 290 | 291 | /** 292 | * drawable转bitmap 293 | * 294 | * @param drawable drawable对象 295 | * @return bitmap对象 296 | */ 297 | public static Bitmap drawable2Bitmap(Drawable drawable) { 298 | return drawable == null ? null : ((BitmapDrawable) drawable).getBitmap(); 299 | } 300 | 301 | /** 302 | * bitmap转drawable 303 | * 304 | * @param resources resources对象 305 | * @param bitmap bitmap对象 306 | * @return drawable对象 307 | */ 308 | public static Drawable bitmap2Drawable(Resources resources, Bitmap bitmap) { 309 | return bitmap == null ? null : new BitmapDrawable(resources, bitmap); 310 | } 311 | 312 | /** 313 | * drawable转byteArr 314 | * 315 | * @param drawable drawable对象 316 | * @param format 格式 317 | * @return 字节数组 318 | */ 319 | public static byte[] drawable2Bytes(Drawable drawable, Bitmap.CompressFormat format) { 320 | return bitmap2Bytes(drawable2Bitmap(drawable), format); 321 | } 322 | 323 | /** 324 | * byteArr转drawable 325 | * 326 | * @param resources resources对象 327 | * @param bytes 字节数组 328 | * @return drawable对象 329 | */ 330 | public static Drawable bytes2Drawable(Resources resources, byte[] bytes) { 331 | return bitmap2Drawable(resources, bytes2Bitmap(bytes)); 332 | } 333 | 334 | /** 335 | * dp转px 336 | * 337 | * @param context 上下文 338 | * @param dpValue dp值 339 | * @return px值 340 | */ 341 | public static int dp2px(Context context, float dpValue) { 342 | final float scale = context.getResources().getDisplayMetrics().density; 343 | return (int) (dpValue * scale + 0.5f); 344 | } 345 | 346 | /** 347 | * px转dp 348 | * 349 | * @param context 上下文 350 | * @param pxValue px值 351 | * @return dp值 352 | */ 353 | public static int px2dp(Context context, float pxValue) { 354 | final float scale = context.getResources().getDisplayMetrics().density; 355 | return (int) (pxValue / scale + 0.5f); 356 | } 357 | 358 | /** 359 | * sp转px 360 | * 361 | * @param context 上下文 362 | * @param spValue sp值 363 | * @return px值 364 | */ 365 | public static int sp2px(Context context, float spValue) { 366 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 367 | return (int) (spValue * fontScale + 0.5f); 368 | } 369 | 370 | /** 371 | * px转sp 372 | * 373 | * @param context 上下文 374 | * @param pxValue px值 375 | * @return sp值 376 | */ 377 | public static int px2sp(Context context, float pxValue) { 378 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 379 | return (int) (pxValue / fontScale + 0.5f); 380 | } 381 | } 382 | -------------------------------------------------------------------------------- /utilcode/src/main/java/com/blankj/utilcode/utils/PhoneUtils.java: -------------------------------------------------------------------------------- 1 | package com.blankj.utilcode.utils; 2 | 3 | import android.content.ContentResolver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.database.Cursor; 7 | import android.net.Uri; 8 | import android.os.SystemClock; 9 | import android.provider.Settings; 10 | import android.telephony.TelephonyManager; 11 | import android.util.Log; 12 | import android.util.Xml; 13 | 14 | import org.xmlpull.v1.XmlSerializer; 15 | 16 | import java.io.File; 17 | import java.io.FileOutputStream; 18 | import java.util.ArrayList; 19 | import java.util.HashMap; 20 | import java.util.List; 21 | 22 | /** 23 | *24 | * author: Blankj 25 | * blog : http://blankj.com 26 | * time : 2016/8/2 27 | * desc : 手机相关工具类 28 | *29 | */ 30 | public class PhoneUtils { 31 | 32 | private PhoneUtils() { 33 | throw new UnsupportedOperationException("u can't fuck me..."); 34 | } 35 | 36 | /** 37 | * 判断设备是否是手机 38 | * 39 | * @param context 上下文 40 | * @return {@code true}: 是
需与{@link #isPhone(Context)}一起使用
50 | *需添加权限 {@code
需添加权限 {@code
需添加权限 {@code
需添加权限 {@code
需添加权限 {@code
参照以下注释代码
212 | */ 213 | public static void getContantNum() { 214 | Log.i("tips", "U should copy the following code."); 215 | /* 216 | Intent intent = new Intent(); 217 | intent.setAction("android.intent.action.PICK"); 218 | intent.setType("vnd.android.cursor.dir/phone_v2"); 219 | startActivityForResult(intent, 0); 220 | 221 | @Override 222 | protected void onActivityResult ( int requestCode, int resultCode, Intent data){ 223 | super.onActivityResult(requestCode, resultCode, data); 224 | if (data != null) { 225 | Uri uri = data.getData(); 226 | String num = null; 227 | // 创建内容解析者 228 | ContentResolver contentResolver = getContentResolver(); 229 | Cursor cursor = contentResolver.query(uri, 230 | null, null, null, null); 231 | while (cursor.moveToNext()) { 232 | num = cursor.getString(cursor.getColumnIndex("data1")); 233 | } 234 | cursor.close(); 235 | num = num.replaceAll("-", "");//替换的操作,555-6 -> 5556 236 | } 237 | } 238 | */ 239 | } 240 | 241 | /** 242 | * 获取手机短信并保存到xml中 243 | *需添加权限 {@code
需添加权限 {@code
13 | * author: Blankj 14 | * blog : http://blankj.com 15 | * time : 2016/8/2 16 | * desc : 时间相关工具类 17 | *18 | */ 19 | public class TimeUtils { 20 | 21 | private TimeUtils() { 22 | throw new UnsupportedOperationException("u can't fuck me..."); 23 | } 24 | 25 | /** 26 | *
在工具类中经常使用到工具类的格式化描述,这个主要是一个日期的操作类,所以日志格式主要使用 SimpleDateFormat的定义格式.
27 | * 格式的意义如下: 日期和时间模式日期和时间格式由日期和时间模式字符串指定。在日期和时间模式字符串中,未加引号的字母 'A' 到 'Z' 和 'a' 到 'z' 29 | * 被解释为模式字母,用来表示日期或时间字符串元素。文本可以使用单引号 (') 引起来,以免进行解释。"''" 30 | * 表示单引号。所有其他字符均不解释;只是在格式化时将它们简单复制到输出字符串,或者在分析时与输入字符串进行匹配。 31 | *
32 | * 定义了以下模式字母(所有其他字符 'A' 到 'Z' 和 'a' 到 'z' 都被保留):| 字母 | 37 | *日期或时间元素 | 38 | *表示 | 39 | *示例 | 40 | *
|---|---|---|---|
G |
43 | * Era 标志符 | 44 | *Text | 45 | *AD |
46 | *
y |
49 | * 年 | 50 | *Year | 51 | *1996; 96 |
52 | *
M |
55 | * 年中的月份 | 56 | *Month | 57 | *July; Jul; 07 |
58 | *
w |
61 | * 年中的周数 | 62 | *Number | 63 | *27 |
64 | *
W |
67 | * 月份中的周数 | 68 | *Number | 69 | *2 |
70 | *
D |
73 | * 年中的天数 | 74 | *Number | 75 | *189 |
76 | *
d |
79 | * 月份中的天数 | 80 | *Number | 81 | *10 |
82 | *
F |
85 | * 月份中的星期 | 86 | *Number | 87 | *2 |
88 | *
E |
91 | * 星期中的天数 | 92 | *Text | 93 | *Tuesday; Tue |
94 | *
a |
97 | * Am/pm 标记 | 98 | *Text | 99 | *PM |
100 | *
H |
103 | * 一天中的小时数(0-23) | 104 | *Number | 105 | *0 |
106 | *
k |
109 | * 一天中的小时数(1-24) | 110 | *Number | 111 | *24 |
112 | *
K |
115 | * am/pm 中的小时数(0-11) | 116 | *Number | 117 | *0 |
118 | *
h |
121 | * am/pm 中的小时数(1-12) | 122 | *Number | 123 | *12 |
124 | *
m |
127 | * 小时中的分钟数 | 128 | *Number | 129 | *30 |
130 | *
s |
133 | * 分钟中的秒数 | 134 | *Number | 135 | *55 |
136 | *
S |
139 | * 毫秒数 | 140 | *Number | 141 | *978 |
142 | *
z |
145 | * 时区 | 146 | *General time zone | 147 | *Pacific Standard Time; PST; GMT-08:00 |
148 | *
Z |
151 | * 时区 | 152 | *RFC 822 time zone | 153 | *-0800 |
154 | *
157 | * HH:mm 15:44
158 | * h:mm a 3:44 下午
159 | * HH:mm z 15:44 CST
160 | * HH:mm Z 15:44 +0800
161 | * HH:mm zzzz 15:44 中国标准时间
162 | * HH:mm:ss 15:44:40
163 | * yyyy-MM-dd 2016-08-12
164 | * yyyy-MM-dd HH:mm 2016-08-12 15:44
165 | * yyyy-MM-dd HH:mm:ss 2016-08-12 15:44:40
166 | * yyyy-MM-dd HH:mm:ss zzzz 2016-08-12 15:44:40 中国标准时间
167 | * EEEE yyyy-MM-dd HH:mm:ss zzzz 星期五 2016-08-12 15:44:40 中国标准时间
168 | * yyyy-MM-dd HH:mm:ss.SSSZ 2016-08-12 15:44:40.461+0800
169 | * yyyy-MM-dd'T'HH:mm:ss.SSSZ 2016-08-12T15:44:40.461+0800
170 | * yyyy.MM.dd G 'at' HH:mm:ss z 2016.08.12 公元 at 15:44:40 CST
171 | * K:mm a 3:44 下午
172 | * EEE, MMM d, ''yy 星期五, 八月 12, '16
173 | * hh 'o''clock' a, zzzz 03 o'clock 下午, 中国标准时间
174 | * yyyyy.MMMMM.dd GGG hh:mm aaa 02016.八月.12 公元 03:44 下午
175 | * EEE, d MMM yyyy HH:mm:ss Z 星期五, 12 八月 2016 15:44:40 +0800
176 | * yyMMddHHmmssZ 160812154440+0800
177 | * yyyy-MM-dd'T'HH:mm:ss.SSSZ 2016-08-12T15:44:40.461+0800
178 | * EEEE 'DATE('yyyy-MM-dd')' 'TIME('HH:mm:ss')' zzzz 星期五 DATE(2016-08-12) TIME(15:44:40) 中国标准时间
179 | *
180 | */
181 | public static final SimpleDateFormat DEFAULT_SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
182 |
183 |
184 | /**
185 | * 将时间戳转为时间字符串
186 | * 格式为yyyy-MM-dd HH:mm:ss
187 | * 188 | * @param milliseconds 毫秒时间戳 189 | * @return 时间字符串 190 | */ 191 | public static String milliseconds2String(long milliseconds) { 192 | return milliseconds2String(milliseconds, DEFAULT_SDF); 193 | } 194 | 195 | /** 196 | * 将时间戳转为时间字符串 197 | *格式为用户自定义
198 | * 199 | * @param milliseconds 毫秒时间戳 200 | * @param format 时间格式 201 | * @return 时间字符串 202 | */ 203 | public static String milliseconds2String(long milliseconds, SimpleDateFormat format) { 204 | return format.format(new Date(milliseconds)); 205 | } 206 | 207 | /** 208 | * 将时间字符串转为时间戳 209 | *格式为yyyy-MM-dd HH:mm:ss
210 | * 211 | * @param time 时间字符串 212 | * @return 毫秒时间戳 213 | */ 214 | public static long string2Milliseconds(String time) { 215 | return string2Milliseconds(time, DEFAULT_SDF); 216 | } 217 | 218 | /** 219 | * 将时间字符串转为时间戳 220 | *格式为用户自定义
221 | * 222 | * @param time 时间字符串 223 | * @param format 时间格式 224 | * @return 毫秒时间戳 225 | */ 226 | public static long string2Milliseconds(String time, SimpleDateFormat format) { 227 | try { 228 | return format.parse(time).getTime(); 229 | } catch (ParseException e) { 230 | e.printStackTrace(); 231 | } 232 | return -1; 233 | } 234 | 235 | /** 236 | * 将时间字符串转为Date类型 237 | *格式为yyyy-MM-dd HH:mm:ss
238 | * 239 | * @param time 时间字符串 240 | * @return Date类型 241 | */ 242 | public static Date string2Date(String time) { 243 | return string2Date(time, DEFAULT_SDF); 244 | } 245 | 246 | /** 247 | * 将时间字符串转为Date类型 248 | *格式为用户自定义
249 | * 250 | * @param time 时间字符串 251 | * @param format 时间格式 252 | * @return Date类型 253 | */ 254 | public static Date string2Date(String time, SimpleDateFormat format) { 255 | return new Date(string2Milliseconds(time, format)); 256 | } 257 | 258 | /** 259 | * 将Date类型转为时间字符串 260 | *格式为yyyy-MM-dd HH:mm:ss
261 | * 262 | * @param time Date类型时间 263 | * @return 时间字符串 264 | */ 265 | public static String date2String(Date time) { 266 | return date2String(time, DEFAULT_SDF); 267 | } 268 | 269 | /** 270 | * 将Date类型转为时间字符串 271 | *格式为用户自定义
272 | * 273 | * @param time Date类型时间 274 | * @param format 时间格式 275 | * @return 时间字符串 276 | */ 277 | public static String date2String(Date time, SimpleDateFormat format) { 278 | return format.format(time); 279 | } 280 | 281 | /** 282 | * 将Date类型转为时间戳 283 | * 284 | * @param time Date类型时间 285 | * @return 毫秒时间戳 286 | */ 287 | public static long date2Milliseconds(Date time) { 288 | return time.getTime(); 289 | } 290 | 291 | /** 292 | * 将时间戳转为Date类型 293 | * 294 | * @param milliseconds 毫秒时间戳 295 | * @return Date类型时间 296 | */ 297 | public static Date milliseconds2Date(long milliseconds) { 298 | return new Date(milliseconds); 299 | } 300 | 301 | /** 302 | * 毫秒时间戳单位转换(单位:unit) 303 | * 304 | * @param milliseconds 毫秒时间戳 305 | * @param unittime1和time2格式都为yyyy-MM-dd HH:mm:ss
333 | * 334 | * @param time0 时间字符串1 335 | * @param time1 时间字符串2 336 | * @param unittime1和time2格式都为format
352 | * 353 | * @param time0 时间字符串1 354 | * @param time1 时间字符串2 355 | * @param unittime1和time2都为Date类型
373 | * 374 | * @param time0 Date类型时间1 375 | * @param time1 Date类型时间2 376 | * @param unit格式为yyyy-MM-dd HH:mm:ss
402 | * 403 | * @return 时间字符串 404 | */ 405 | public static String getCurTimeString() { 406 | return date2String(new Date()); 407 | } 408 | 409 | /** 410 | * 获取当前时间 411 | *格式为用户自定义
412 | * 413 | * @param format 时间格式 414 | * @return 时间字符串 415 | */ 416 | public static String getCurTimeString(SimpleDateFormat format) { 417 | return date2String(new Date(), format); 418 | } 419 | 420 | /** 421 | * 获取当前时间 422 | *Date类型
423 | * 424 | * @return Date类型时间 425 | */ 426 | public static Date getCurTimeDate() { 427 | return new Date(); 428 | } 429 | 430 | /** 431 | * 获取与当前时间的差(单位:unit) 432 | *time格式为yyyy-MM-dd HH:mm:ss
433 | * 434 | * @param time 时间字符串 435 | * @param unittime格式为format
451 | * 452 | * @param time 时间字符串 453 | * @param unittime为Date类型
470 | * 471 | * @param time Date类型时间 472 | * @param unit19 | * author: Blankj 20 | * blog : http://blankj.com 21 | * time : 2016/8/2 22 | * desc : 加密解密相关的工具类 23 | *24 | */ 25 | public class EncryptUtils { 26 | 27 | private EncryptUtils() { 28 | throw new UnsupportedOperationException("u can't fuck me..."); 29 | } 30 | 31 | /*********************** 哈希加密相关 ***********************/ 32 | /** 33 | * MD2加密 34 | * 35 | * @param data 明文字符串 36 | * @return 16进制密文 37 | */ 38 | public static String encryptMD2ToString(String data) { 39 | return encryptMD2ToString(data.getBytes()); 40 | } 41 | 42 | /** 43 | * MD2加密 44 | * 45 | * @param data 明文字节数组 46 | * @return 16进制密文 47 | */ 48 | public static String encryptMD2ToString(byte[] data) { 49 | return bytes2HexString(encryptMD2(data)); 50 | } 51 | 52 | /** 53 | * MD2加密 54 | * 55 | * @param data 明文字节数组 56 | * @return 密文字节数组 57 | */ 58 | public static byte[] encryptMD2(byte[] data) { 59 | return encryptAlgorithm(data, "MD2"); 60 | } 61 | 62 | /** 63 | * MD5加密 64 | * 65 | * @param data 明文字符串 66 | * @return 16进制密文 67 | */ 68 | public static String encryptMD5ToString(String data) { 69 | return encryptMD5ToString(data.getBytes()); 70 | } 71 | 72 | /** 73 | * MD5加密 74 | * 75 | * @param data 明文字符串 76 | * @param salt 盐 77 | * @return 16进制加盐密文 78 | */ 79 | public static String encryptMD5ToString(String data, String salt) { 80 | return bytes2HexString(encryptMD5((data + salt).getBytes())); 81 | } 82 | 83 | /** 84 | * MD5加密 85 | * 86 | * @param data 明文字节数组 87 | * @return 16进制密文 88 | */ 89 | public static String encryptMD5ToString(byte[] data) { 90 | return bytes2HexString(encryptMD5(data)); 91 | } 92 | 93 | /** 94 | * MD5加密 95 | * 96 | * @param data 明文字节数组 97 | * @param salt 盐字节数组 98 | * @return 16进制加盐密文 99 | */ 100 | public static String encryptMD5ToString(byte[] data, byte[] salt) { 101 | byte[] dataSalt = new byte[data.length + salt.length]; 102 | System.arraycopy(data, 0, dataSalt, 0, data.length); 103 | System.arraycopy(salt, 0, dataSalt, data.length, salt.length); 104 | return bytes2HexString(encryptMD5(dataSalt)); 105 | } 106 | 107 | /** 108 | * MD5加密 109 | * 110 | * @param data 明文字节数组 111 | * @return 密文字节数组 112 | */ 113 | public static byte[] encryptMD5(byte[] data) { 114 | return encryptAlgorithm(data, "MD5"); 115 | } 116 | 117 | /** 118 | * SHA1加密 119 | * 120 | * @param data 明文字符串 121 | * @return 16进制密文 122 | */ 123 | public static String encryptSHA1ToString(String data) { 124 | return encryptSHA1ToString(data.getBytes()); 125 | } 126 | 127 | /** 128 | * SHA1加密 129 | * 130 | * @param data 明文字节数组 131 | * @return 16进制密文 132 | */ 133 | public static String encryptSHA1ToString(byte[] data) { 134 | return bytes2HexString(encryptSHA1(data)); 135 | } 136 | 137 | /** 138 | * SHA1加密 139 | * 140 | * @param data 明文字节数组 141 | * @return 密文字节数组 142 | */ 143 | public static byte[] encryptSHA1(byte[] data) { 144 | return encryptAlgorithm(data, "SHA-1"); 145 | } 146 | 147 | /** 148 | * SHA224加密 149 | * 150 | * @param data 明文字符串 151 | * @return 16进制密文 152 | */ 153 | public static String encryptSHA224ToString(String data) { 154 | return encryptSHA224ToString(data.getBytes()); 155 | } 156 | 157 | /** 158 | * SHA224加密 159 | * 160 | * @param data 明文字节数组 161 | * @return 16进制密文 162 | */ 163 | public static String encryptSHA224ToString(byte[] data) { 164 | return bytes2HexString(encryptSHA224(data)); 165 | } 166 | 167 | /** 168 | * SHA224加密 169 | * 170 | * @param data 明文字节数组 171 | * @return 密文字节数组 172 | */ 173 | public static byte[] encryptSHA224(byte[] data) { 174 | return encryptAlgorithm(data, "SHA-224"); 175 | } 176 | 177 | /** 178 | * SHA256加密 179 | * 180 | * @param data 明文字符串 181 | * @return 16进制密文 182 | */ 183 | public static String encryptSHA256ToString(String data) { 184 | return encryptSHA256ToString(data.getBytes()); 185 | } 186 | 187 | /** 188 | * SHA256加密 189 | * 190 | * @param data 明文字节数组 191 | * @return 16进制密文 192 | */ 193 | public static String encryptSHA256ToString(byte[] data) { 194 | return bytes2HexString(encryptSHA256(data)); 195 | } 196 | 197 | /** 198 | * SHA256加密 199 | * 200 | * @param data 明文字节数组 201 | * @return 密文字节数组 202 | */ 203 | public static byte[] encryptSHA256(byte[] data) { 204 | return encryptAlgorithm(data, "SHA-256"); 205 | } 206 | 207 | /** 208 | * SHA384加密 209 | * 210 | * @param data 明文字符串 211 | * @return 16进制密文 212 | */ 213 | public static String encryptSHA384ToString(String data) { 214 | return encryptSHA384ToString(data.getBytes()); 215 | } 216 | 217 | /** 218 | * SHA384加密 219 | * 220 | * @param data 明文字节数组 221 | * @return 16进制密文 222 | */ 223 | public static String encryptSHA384ToString(byte[] data) { 224 | return bytes2HexString(encryptSHA384(data)); 225 | } 226 | 227 | /** 228 | * SHA384加密 229 | * 230 | * @param data 明文字节数组 231 | * @return 密文字节数组 232 | */ 233 | public static byte[] encryptSHA384(byte[] data) { 234 | return encryptAlgorithm(data, "SHA-384"); 235 | } 236 | 237 | /** 238 | * SHA512加密 239 | * 240 | * @param data 明文字符串 241 | * @return 16进制密文 242 | */ 243 | public static String encryptSHA512ToString(String data) { 244 | return encryptSHA512ToString(data.getBytes()); 245 | } 246 | 247 | /** 248 | * SHA512加密 249 | * 250 | * @param data 明文字节数组 251 | * @return 16进制密文 252 | */ 253 | public static String encryptSHA512ToString(byte[] data) { 254 | return bytes2HexString(encryptSHA512(data)); 255 | } 256 | 257 | /** 258 | * SHA512加密 259 | * 260 | * @param data 明文字节数组 261 | * @return 密文字节数组 262 | */ 263 | public static byte[] encryptSHA512(byte[] data) { 264 | return encryptAlgorithm(data, "SHA-512"); 265 | } 266 | 267 | /** 268 | * 对data进行algorithm算法加密 269 | * 270 | * @param data 明文字节数组 271 | * @param algorithm 加密算法 272 | * @return 密文字节数组 273 | */ 274 | private static byte[] encryptAlgorithm(byte[] data, String algorithm) { 275 | try { 276 | MessageDigest md = MessageDigest.getInstance(algorithm); 277 | md.update(data); 278 | return md.digest(); 279 | } catch (NoSuchAlgorithmException e) { 280 | e.printStackTrace(); 281 | } 282 | return new byte[0]; 283 | } 284 | 285 | /** 286 | * 获取文件的MD5校验码 287 | * 288 | * @param filePath 文件路径 289 | * @return 文件的16进制密文 290 | */ 291 | public static String encryptMD5File2String(String filePath) { 292 | return encryptMD5File2String(new File(filePath)); 293 | } 294 | 295 | /** 296 | * 获取文件的MD5校验码 297 | * 298 | * @param filePath 文件路径 299 | * @return 文件的MD5校验码 300 | */ 301 | public static byte[] encryptMD5File(String filePath) { 302 | return encryptMD5File(new File(filePath)); 303 | } 304 | 305 | /** 306 | * 获取文件的MD5校验码 307 | * 308 | * @param file 文件 309 | * @return 文件的16进制密文 310 | */ 311 | public static String encryptMD5File2String(File file) { 312 | return encryptMD5File(file) != null ? bytes2HexString(encryptMD5File(file)) : ""; 313 | } 314 | 315 | /** 316 | * 获取文件的MD5校验码 317 | * 318 | * @param file 文件 319 | * @return 文件的MD5校验码 320 | */ 321 | public static byte[] encryptMD5File(File file) { 322 | FileInputStream in = null; 323 | try { 324 | in = new FileInputStream(file); 325 | FileChannel channel = in.getChannel(); 326 | MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); 327 | MessageDigest md = MessageDigest.getInstance("MD5"); 328 | md.update(buffer); 329 | return md.digest(); 330 | } catch (NoSuchAlgorithmException | IOException e) { 331 | e.printStackTrace(); 332 | } finally { 333 | if (in != null) { 334 | try { 335 | in.close(); 336 | } catch (IOException ignored) { 337 | } 338 | } 339 | } 340 | return null; 341 | } 342 | 343 | /************************ DES加密相关 ***********************/ 344 | /** 345 | * DES转变 346 | *
法算法名称/加密模式/填充方式
347 | *加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB
348 | *填充方式有:NoPadding、ZerosPadding、PKCS5Padding
349 | */ 350 | public static String DES_Transformation = "DES/ECB/NoPadding"; 351 | private static final String DES_Algorithm = "DES"; 352 | 353 | /** 354 | * @param data 数据 355 | * @param key 秘钥 356 | * @param algorithm 采用何种DES算法 357 | * @param transformation 转变 358 | * @param isEncrypt 是否加密 359 | * @return 密文或者明文,适用于DES,3DES,AES 360 | */ 361 | public static byte[] DESTemplet(byte[] data, byte[] key, String algorithm, String transformation, boolean isEncrypt) { 362 | try { 363 | SecretKeySpec keySpec = new SecretKeySpec(key, algorithm); 364 | Cipher cipher = Cipher.getInstance(transformation); 365 | SecureRandom random = new SecureRandom(); 366 | cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, keySpec, random); 367 | return cipher.doFinal(data); 368 | } catch (Throwable e) { 369 | e.printStackTrace(); 370 | } 371 | return null; 372 | } 373 | 374 | /** 375 | * DES加密后转为Base64编码 376 | * 377 | * @param data 明文 378 | * @param key 8字节秘钥 379 | * @return Base64密文 380 | */ 381 | public static byte[] encryptDES2Base64(byte[] data, byte[] key) { 382 | return EncodeUtils.base64Encode(encryptDES(data, key)); 383 | } 384 | 385 | /** 386 | * DES加密后转为16进制 387 | * 388 | * @param data 明文 389 | * @param key 8字节秘钥 390 | * @return 16进制密文 391 | */ 392 | public static String encryptDES2HexString(byte[] data, byte[] key) { 393 | return bytes2HexString(encryptDES(data, key)); 394 | } 395 | 396 | /** 397 | * DES加密 398 | * 399 | * @param data 明文 400 | * @param key 8字节秘钥 401 | * @return 密文 402 | */ 403 | public static byte[] encryptDES(byte[] data, byte[] key) { 404 | return DESTemplet(data, key, DES_Algorithm, DES_Transformation, true); 405 | } 406 | 407 | /** 408 | * DES解密Base64编码密文 409 | * 410 | * @param data Base64编码密文 411 | * @param key 8字节秘钥 412 | * @return 明文 413 | */ 414 | public static byte[] decryptBase64DES(byte[] data, byte[] key) { 415 | return decryptDES(EncodeUtils.base64Decode(data), key); 416 | } 417 | 418 | /** 419 | * DES解密16进制密文 420 | * 421 | * @param data 16进制密文 422 | * @param key 8字节秘钥 423 | * @return 明文 424 | */ 425 | public static byte[] decryptHexStringDES(String data, byte[] key) { 426 | return decryptDES(hexString2Bytes(data), key); 427 | } 428 | 429 | /** 430 | * DES解密 431 | * 432 | * @param data 密文 433 | * @param key 8字节秘钥 434 | * @return 明文 435 | */ 436 | public static byte[] decryptDES(byte[] data, byte[] key) { 437 | return DESTemplet(data, key, DES_Algorithm, DES_Transformation, false); 438 | } 439 | 440 | /************************ 3DES加密相关 ***********************/ 441 | /** 442 | * 3DES转变 443 | *法算法名称/加密模式/填充方式
444 | *加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB
445 | *填充方式有:NoPadding、ZerosPadding、PKCS5Padding
446 | */ 447 | public static String TripleDES_Transformation = "DESede/ECB/NoPadding"; 448 | private static final String TripleDES_Algorithm = "DESede"; 449 | 450 | 451 | /** 452 | * 3DES加密后转为Base64编码 453 | * 454 | * @param data 明文 455 | * @param key 24字节秘钥 456 | * @return Base64密文 457 | */ 458 | public static byte[] encrypt3DES2Base64(byte[] data, byte[] key) { 459 | return EncodeUtils.base64Encode(encrypt3DES(data, key)); 460 | } 461 | 462 | /** 463 | * 3DES加密后转为16进制 464 | * 465 | * @param data 明文 466 | * @param key 24字节秘钥 467 | * @return 16进制密文 468 | */ 469 | public static String encrypt3DES2HexString(byte[] data, byte[] key) { 470 | return bytes2HexString(encrypt3DES(data, key)); 471 | } 472 | 473 | /** 474 | * 3DES加密 475 | * 476 | * @param data 明文 477 | * @param key 24字节密钥 478 | * @return 密文 479 | */ 480 | public static byte[] encrypt3DES(byte[] data, byte[] key) { 481 | return DESTemplet(data, key, TripleDES_Algorithm, TripleDES_Transformation, true); 482 | } 483 | 484 | /** 485 | * 3DES解密Base64编码密文 486 | * 487 | * @param data Base64编码密文 488 | * @param key 24字节秘钥 489 | * @return 明文 490 | */ 491 | public static byte[] decryptBase64_3DES(byte[] data, byte[] key) { 492 | return decrypt3DES(EncodeUtils.base64Decode(data), key); 493 | } 494 | 495 | /** 496 | * 3DES解密16进制密文 497 | * 498 | * @param data 16进制密文 499 | * @param key 24字节秘钥 500 | * @return 明文 501 | */ 502 | public static byte[] decryptHexString3DES(String data, byte[] key) { 503 | return decrypt3DES(hexString2Bytes(data), key); 504 | } 505 | 506 | /** 507 | * 3DES解密 508 | * 509 | * @param data 密文 510 | * @param key 24字节密钥 511 | * @return 明文 512 | */ 513 | public static byte[] decrypt3DES(byte[] data, byte[] key) { 514 | return DESTemplet(data, key, TripleDES_Algorithm, TripleDES_Transformation, false); 515 | } 516 | 517 | /************************ AES加密相关 ***********************/ 518 | /** 519 | * AES转变 520 | *法算法名称/加密模式/填充方式
521 | *加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB
522 | *填充方式有:NoPadding、ZerosPadding、PKCS5Padding
523 | */ 524 | public static String AES_Transformation = "AES/ECB/NoPadding"; 525 | private static final String AES_Algorithm = "AES"; 526 | 527 | 528 | /** 529 | * AES加密后转为Base64编码 530 | * 531 | * @param data 明文 532 | * @param key 16、24、32字节秘钥 533 | * @return Base64密文 534 | */ 535 | public static byte[] encryptAES2Base64(byte[] data, byte[] key) { 536 | return EncodeUtils.base64Encode(encryptAES(data, key)); 537 | } 538 | 539 | /** 540 | * AES加密后转为16进制 541 | * 542 | * @param data 明文 543 | * @param key 16、24、32字节秘钥 544 | * @return 16进制密文 545 | */ 546 | public static String encryptAES2HexString(byte[] data, byte[] key) { 547 | return bytes2HexString(encryptAES(data, key)); 548 | } 549 | 550 | /** 551 | * AES加密 552 | * 553 | * @param data 明文 554 | * @param key 16、24、32字节秘钥 555 | * @return 密文 556 | */ 557 | public static byte[] encryptAES(byte[] data, byte[] key) { 558 | return DESTemplet(data, key, AES_Algorithm, AES_Transformation, true); 559 | } 560 | 561 | /** 562 | * AES解密Base64编码密文 563 | * 564 | * @param data Base64编码密文 565 | * @param key 16、24、32字节秘钥 566 | * @return 明文 567 | */ 568 | public static byte[] decryptBase64AES(byte[] data, byte[] key) { 569 | return decryptAES(EncodeUtils.base64Decode(data), key); 570 | } 571 | 572 | /** 573 | * AES解密16进制密文 574 | * 575 | * @param data 16进制密文 576 | * @param key 16、24、32字节秘钥 577 | * @return 明文 578 | */ 579 | public static byte[] decryptHexStringAES(String data, byte[] key) { 580 | return decryptAES(hexString2Bytes(data), key); 581 | } 582 | 583 | /** 584 | * AES解密 585 | * 586 | * @param data 密文 587 | * @param key 16、24、32字节秘钥 588 | * @return 明文 589 | */ 590 | public static byte[] decryptAES(byte[] data, byte[] key) { 591 | return DESTemplet(data, key, AES_Algorithm, AES_Transformation, false); 592 | } 593 | } --------------------------------------------------------------------------------