├── README.md ├── about_app.md ├── about_device.md ├── about_encrypt.md ├── about_keyboard.md ├── about_network.md ├── about_phone.md ├── about_regular.md ├── about_screen.md ├── about_size.md ├── about_time.md ├── about_unclassified.md ├── update_log.md └── utilcode ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── src ├── androidTest │ └── java │ │ └── com │ │ └── blankj │ │ └── utilcode │ │ └── ApplicationTest.java ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── blankj │ │ │ └── utilcode │ │ │ └── utils │ │ │ ├── AppUtils.java │ │ │ ├── DeviceUtils.java │ │ │ ├── EncryptUtils.java │ │ │ ├── KeyboardUtils.java │ │ │ ├── NetworkUtils.java │ │ │ ├── PhoneUtils.java │ │ │ ├── RegularUtils.java │ │ │ ├── ScreenUtils.java │ │ │ ├── SizeUtils.java │ │ │ ├── TimeUtils.java │ │ │ └── UnclassifiedUtils.java │ └── res │ │ └── values │ │ └── strings.xml └── test │ └── java │ └── com │ └── blankj │ └── utilcode │ └── utils │ └── EncryptUtilsTest.java └── utilcode.iml /README.md: -------------------------------------------------------------------------------- 1 | # Android开发人员不得不收集的代码(持续更新中) 2 | 为方便查找,已进行大致归类,其目录如下所示: 3 | > - [App相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_app.md)→[AppUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/AppUtils.java) 4 | > - 安装指定路径下的Apk *installApp* 5 | > - 卸载指定包名的App *uninstallApp* 6 | > - 获取当前App信息 *getAppInfo* 7 | > - 获取所有已安装App信息 *getAllAppsInfo* 8 | > - 打开指定包名的App *openAppByPackageName* 9 | > - 打开指定包名的App应用信息界面 *openAppInfo* 10 | > - 可用来做App信息分享 *shareAppInfo* 11 | > - 判断当前App处于前台还是后台 *isApplicationBackground* 12 | 13 | > - [设备相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_device.md)→[DeviceUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/DeviceUtils.java) 14 | > - 获取设备MAC地址 *getMacAddress* 15 | > - 获取设备厂商,如Xiaomi *getManufacturer* 16 | > - 获取设备型号,如MI2SC *getModel* 17 | > - 获取设备SD卡是否可用 *isSDCardEnable* 18 | > - 获取设备SD卡路径 *getSDCardPath* 19 | 20 | > - [加解密相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_encrypt.md)→[EncryptUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/EncryptUtils.java) 21 | > - MD5加密 *getMD5* *encryptMD5* *getMD5File* 22 | > - SHA加密 *getSHA* *encryptSHA* 23 | 24 | > - [键盘相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_keyboard.md)→[KeyboardUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/KeyboardUtils.java) 25 | > - 避免输入法面板遮挡 26 | > - 动态隐藏软键盘 *hideSoftInput* 27 | > - 点击屏幕空白区域隐藏软键盘(注释萌萌哒) *clickBlankArea2HideSoftInput0* 28 | > - 动态显示软键盘 *showSoftInput* 29 | > - 切换键盘显示与否状态 *toggleSoftInput* 30 | 31 | > - [网络相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_network.md)→[NetworkUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/NetworkUtils.java) 32 | > - 打开网络设置界面 *openWirelessSettings* 33 | > - 判断网络是否可用 *isAvailable* 34 | > - 判断网络是否连接 *isConnected* 35 | > - 判断网络是否是4G *is4G* 36 | > - 判断wifi是否连接状态 *isWifiConnected* 37 | > - 获取移动网络运营商名称 *getNetworkOperatorName* 38 | > - 获取移动终端类型 *getPhoneType* 39 | > - 获取当前的网络类型(WIFI,2G,3G,4G) *getNetWorkType* *getNetWorkTypeName* 40 | 41 | > - [手机相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_phone.md)→[PhoneUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/PhoneUtils.java) 42 | > - 判断设备是否是手机 *isPhone* 43 | > - 获取手机的IMIE *getDeviceIMEI* 44 | > - 获取手机状态信息 *getPhoneStatus* 45 | > - 跳至填充好phoneNumber的拨号界面 *dial* 46 | > - 拨打phoneNumber *call* 47 | > - 发送短信 *sendSms* 48 | > - 获取手机联系人 *getAllContactInfo* 49 | > - 打开手机联系人界面点击联系人后便获取该号码(注释萌萌哒) *getContantNum* 50 | > - 获取手机短信并保存到xml中 *getAllSMS* 51 | 52 | > - [正则相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_regular.md)→[RegularUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/RegularUtils.java) 53 | > - 正则工具类 54 | 55 | > - [屏幕相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_screen.md)→[ScreenUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/ScreenUtils.java) 56 | > - 获取手机分辨率 *getDeviceWidth*、*getDeviceHeight* 57 | > - 设置透明状态栏(api >= 19方可使用) *setTransparentStatusBar* 58 | > - 隐藏状态栏(注释萌萌哒) *hideStatusBar* 59 | > - 获取状态栏高度 *getStatusBarHeight* 60 | > - 判断状态栏是否存在 *isStatusBarExists* 61 | > - 获取ActionBar高度 *getActionBarHeight* 62 | > - 设置屏幕为横屏(注释萌萌哒) *setLandscape* 63 | > - 获取屏幕截图 *snapShotWithStatusBar*、*snapShotWithoutStatusBar* 64 | > - 判断是否锁屏 *isScreenLock* 65 | 66 | > - [尺寸相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_size.md)→[SizeUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/SizeUtils.java) 67 | > - dp与px转换 *dp2px*、*px2dp* 68 | > - sp与px转换 *sp2px*、*px2sp* 69 | > - 各种单位转换 *applyDimension* 70 | > - 在onCreate()即可强行获取View的尺寸 *forceGetViewSize* 71 | > - ListView中提前测量View尺寸(注释萌萌哒) *measureView* 72 | 73 | > - [时间相关](https://github.com/Blankj/AndroidUtilCode/blob/master/about_time.md)→[TimeUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/TimeUtils.java) 74 | > - 将时间戳转为时间字符串 *milliseconds2String* 75 | > - 将时间字符串转为时间戳 *string2Milliseconds* 76 | > - 将时间字符串转为Date类型 *string2Date* 77 | > - 将Date类型转为时间字符串 *date2String* 78 | > - 将Date类型转为时间戳 *date2Milliseconds* 79 | > - 将时间戳转为Date类型 *milliseconds2Date* 80 | > - 毫秒时间戳单位转换(单位:unit) *milliseconds2Unit* 81 | > - 获取两个时间差(单位:unit) *getIntervalTime* 82 | > - 获取当前时间 *getCurTimeMills* *getCurTimeString* *getCurTimeDate* 83 | > - 获取与当前时间的差(单位:unit) *getIntervalByNow* 84 | > - 判断闰年 *isLeapYear* 85 | 86 | > - [未归类](https://github.com/Blankj/AndroidUtilCode/blob/master/unclassified.md)→[UnclassifiedUtils.java](https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/src/main/java/com/blankj/utilcode/utils/UnclassifiedUtils.java) 87 | > - 获取服务是否开启 *isRunningService* 88 | > - [更新Log](https://github.com/Blankj/AndroidUtilCode/blob/master/update_log.md) 89 | 90 | *** 91 | 92 | **做这份整理只是想把它作为Android的一本小字典,当遇到一些琐碎问题时,不用再面向百度或者谷歌查询API的使用,费时费力,这里有的话,大家尽管撸走。希望它能逐日壮大起来,期待你的Star和完善,用途的话大家想把它们整理成工具类或者什么的话都可以,之后我也会封装工具类并分享之,但本篇只是提供查阅,毕竟看md比看类文件要爽多了,其中好多代码我也是各种搜刮来的,也要谢谢各位的总结,大部分代码已验证过可行,如有错误,请及时告之,开设QQ群提供讨论,群号:74721490** 93 | 94 | # 更新Log 95 | #### 2016/07/31 新增点击屏幕空白区域隐藏软键盘 96 | #### 2016/07/31 未能成功增加本页目录跳转功能(不支持) 97 | #### 2016/08/01 新增获取当前App版本Code 98 | #### 2016/08/01 新增目录中显示方法名 99 | #### 2016/08/01 新增获取SD卡路径,手机和设备进行分类,代码bug修改部分,小修排版,正在封装类 100 | #### 2016/08/02 wifi设置界面bug修复,注释排版还在修改,获取mac地址增加判空,新增QQ群:74721490,欢迎加入 101 | #### 2016/08/02 新增隐藏状态栏,注释更加全面,工具类已封装,写的时候真的是一个一个测试过去的,宝宝心里苦 102 | #### 2016/08/03 修复在onCreate中获取view尺寸的bug,MD5和SHA的Bug修复完成(在此感谢ssyijiu) 103 | #### 2016/08/04 新增时间工具类(在此感谢yi520000给的补充),手机正则分简单和精确(在此感谢MIkeeJY),新增判断是否锁屏,注释分段落,目录按首字母排序 104 | #### 2016/08/05 加密新增MD5盐加密,完善NetworkUtils,新增判断状态栏是否存在(在此感谢tiandawu) 105 | #### 2016/08/06 重命名包名,新增加密相关的单元测试,MD5加密新增文件加密重载。 106 | 107 | 108 | ##[关于Blankj](http://blankj.com/about) -------------------------------------------------------------------------------- /about_app.md: -------------------------------------------------------------------------------- 1 | # App相关 2 | ### 安装指定路径下的Apk 3 | ``` java 4 | /** 5 | * 安装指定路径下的Apk 6 | *
根据路径名是否符合和文件是否存在判断是否安装成功 7 | *
更好的做法应该是startActivityForResult回调判断是否安装成功比较妥当 8 | *
这里做不了回调,后续自己做处理 9 | */ 10 | public static boolean installApp(Context context, String filePath) { 11 | if (filePath != null && filePath.length() > 4 12 | && filePath.toLowerCase().substring(filePath.length() - 4).equals(".apk")) { 13 | Intent intent = new Intent(Intent.ACTION_VIEW); 14 | File file = new File(filePath); 15 | if (file.exists() && file.isFile() && file.length() > 0) { 16 | intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); 17 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 18 | context.startActivity(intent); 19 | return true; 20 | } 21 | } 22 | return false; 23 | } 24 | ``` 25 | 26 | ### 卸载指定包名的App 27 | ``` java 28 | /** 29 | * 卸载指定包名的App 30 | *
这里卸载成不成功只判断了packageName是否为空 31 | *
如果要根据是否卸载成功应该用startActivityForResult回调判断是否还存在比较妥当 32 | *
这里做不了回调,后续自己做处理 33 | */ 34 | public boolean uninstallApp(Context context, String packageName) { 35 | if (!TextUtils.isEmpty(packageName)) { 36 | Intent intent = new Intent(Intent.ACTION_DELETE); 37 | intent.setData(Uri.parse("package:" + packageName)); 38 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 39 | context.startActivity(intent); 40 | return true; 41 | } 42 | return false; 43 | } 44 | ``` 45 | 46 | ### 获取当前App信息 47 | ``` java 48 | /** 49 | * 封装App信息的Bean类 50 | */ 51 | public static class AppInfo { 52 | 53 | private String name; 54 | private Drawable icon; 55 | private String packagName; 56 | private String versionName; 57 | private int versionCode; 58 | private boolean isSD; 59 | private boolean isUser; 60 | 61 | public Drawable getIcon() { 62 | return icon; 63 | } 64 | 65 | public void setIcon(Drawable icon) { 66 | this.icon = icon; 67 | } 68 | 69 | public boolean isSD() { 70 | return isSD; 71 | } 72 | 73 | public void setSD(boolean SD) { 74 | isSD = SD; 75 | } 76 | 77 | public boolean isUser() { 78 | return isUser; 79 | } 80 | 81 | public void setUser(boolean user) { 82 | isUser = user; 83 | } 84 | 85 | public String getName() { 86 | return name; 87 | } 88 | 89 | public void setName(String name) { 90 | this.name = name; 91 | } 92 | 93 | public String getPackagName() { 94 | return packagName; 95 | } 96 | 97 | public void setPackagName(String packagName) { 98 | this.packagName = packagName; 99 | } 100 | 101 | public int getVersionCode() { 102 | return versionCode; 103 | } 104 | 105 | public void setVersionCode(int versionCode) { 106 | this.versionCode = versionCode; 107 | } 108 | 109 | public String getVersionName() { 110 | return versionName; 111 | } 112 | 113 | public void setVersionName(String versionName) { 114 | this.versionName = versionName; 115 | } 116 | 117 | /** 118 | * @param name 名称 119 | * @param icon 图标 120 | * @param packagName 包名 121 | * @param versionName 版本号 122 | * @param versionCode 版本Code 123 | * @param isSD 是否安装在SD卡 124 | * @param isUser 是否是用户程序 125 | */ 126 | public AppInfo(String name, Drawable icon, String packagName, 127 | String versionName, int versionCode, boolean isSD, boolean isUser) { 128 | this.setName(name); 129 | this.setIcon(icon); 130 | this.setPackagName(packagName); 131 | this.setVersionName(versionName); 132 | this.setVersionCode(versionCode); 133 | this.setSD(isSD); 134 | this.setUser(isUser); 135 | } 136 | 137 | /*@Override 138 | public String toString() { 139 | return getName() + "\n" 140 | + getIcon() + "\n" 141 | + getPackagName() + "\n" 142 | + getVersionName() + "\n" 143 | + getVersionCode() + "\n" 144 | + isSD() + "\n" 145 | + isUser() + "\n"; 146 | }*/ 147 | } 148 | 149 | /** 150 | * 获取当前App信息 151 | *
AppInfo(名称,图标,包名,版本号,版本Code,是否安装在SD卡,是否是用户程序) 152 | */ 153 | public static AppInfo getAppInfo(Context context) { 154 | PackageManager pm = context.getPackageManager(); 155 | PackageInfo pi = null; 156 | try { 157 | pi = pm.getPackageInfo(context.getApplicationContext().getPackageName(), 0); 158 | } catch (PackageManager.NameNotFoundException e) { 159 | e.printStackTrace(); 160 | } 161 | return pi != null ? getBean(pm, pi) : null; 162 | } 163 | 164 | /** 165 | * 得到AppInfo的Bean 166 | */ 167 | private static AppInfo getBean(PackageManager pm, PackageInfo pi) { 168 | ApplicationInfo ai = pi.applicationInfo; 169 | String name = ai.loadLabel(pm).toString(); 170 | Drawable icon = ai.loadIcon(pm); 171 | String packageName = pi.packageName; 172 | String versionName = pi.versionName; 173 | int versionCode = pi.versionCode; 174 | boolean isSD = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != ApplicationInfo.FLAG_SYSTEM; 175 | boolean isUser = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != ApplicationInfo.FLAG_SYSTEM; 176 | return new AppInfo(name, icon, packageName, versionName, versionCode, isSD, isUser); 177 | } 178 | ``` 179 | 180 | ### 获取所有已安装App信息 181 | ``` 182 | /** 183 | * 获取所有已安装App信息 184 | *
AppInfo(名称,图标,包名,版本号,版本Code,是否安装在SD卡,是否是用户程序) 185 | *
依赖上面的getBean方法
186 | */
187 | public static List 需添加 并且必须是系统应用该方法才有效
257 | */
258 | public static boolean isAppBackground(Context context) {
259 | ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
260 | @SuppressWarnings("deprecation")
261 | List 需添加权限 一般是/storage/emulated/0/
64 | */
65 | public static String getSDCardPath() {
66 | return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
67 | }
68 | ```
69 |
--------------------------------------------------------------------------------
/about_encrypt.md:
--------------------------------------------------------------------------------
1 | # 加解密相关
2 | ### MD5加密
3 | ``` java
4 | /**
5 | * MD5加密
6 | *
7 | * @param data 明文字符串
8 | * @return 密文
9 | */
10 | public static String getMD5(String data) {
11 | return getMD5(data.getBytes());
12 | }
13 |
14 | /**
15 | * MD5加密
16 | *
17 | * @param data 明文字符串
18 | * @param salt 盐
19 | * @return 密文
20 | */
21 | public static String getMD5(String data, String salt) {
22 | return bytes2Hex(encryptMD5((data + salt).getBytes()));
23 | }
24 |
25 | /**
26 | * MD5加密
27 | *
28 | * @param data 明文字节数组
29 | * @return 密文
30 | */
31 | public static String getMD5(byte[] data) {
32 | return bytes2Hex(encryptMD5(data));
33 | }
34 |
35 | /**
36 | * MD5加密
37 | *
38 | * @param data 明文字节数组
39 | * @param salt 盐字节数组
40 | * @return 密文
41 | */
42 | public static String getMD5(byte[] data, byte[] salt) {
43 | byte[] dataSalt = new byte[data.length + salt.length];
44 | System.arraycopy(data, 0, dataSalt, 0, data.length);
45 | System.arraycopy(salt, 0, dataSalt, data.length, salt.length);
46 | return bytes2Hex(encryptMD5(dataSalt));
47 | }
48 |
49 | /**
50 | * MD5加密
51 | *
52 | * @param data 明文字节数组
53 | * @return 密文字节数组
54 | */
55 | public static byte[] encryptMD5(byte[] data) {
56 | try {
57 | MessageDigest md = MessageDigest.getInstance("MD5");
58 | md.update(data);
59 | return md.digest();
60 | } catch (NoSuchAlgorithmException e) {
61 | e.printStackTrace();
62 | }
63 | return new byte[0];
64 | }
65 |
66 | /**
67 | * 获取文件的MD5校验码
68 | *
69 | * @param filePath 文件路径
70 | * @return 文件的MD5校验码
71 | */
72 | public static String getMD5File(String filePath) {
73 | FileInputStream in = null;
74 | try {
75 | MessageDigest md = MessageDigest.getInstance("MD5");
76 | in = new FileInputStream(filePath);
77 | int len;
78 | byte[] buffer = new byte[1024];
79 | while ((len = in.read(buffer)) != -1) {
80 | md.update(buffer, 0, len);
81 | }
82 | return bytes2Hex(md.digest());
83 | } catch (NoSuchAlgorithmException | IOException e) {
84 | e.printStackTrace();
85 | } finally {
86 | if (in != null) {
87 | try {
88 | in.close();
89 | } catch (IOException ignored) {
90 | }
91 | }
92 | }
93 | return "";
94 | }
95 | ```
96 |
97 | ### SHA加密
98 | ```
99 | /**
100 | * SHA加密
101 | *
102 | * @param data 明文字符串
103 | * @return 密文
104 | */
105 | public static String getSHA(String data) {
106 | return getSHA(data.getBytes());
107 | }
108 |
109 | /**
110 | * SHA加密
111 | *
112 | * @param data 明文字节数组
113 | * @return 密文
114 | */
115 | public static String getSHA(byte[] data) {
116 | return bytes2Hex(encryptSHA(data));
117 | }
118 |
119 | /**
120 | * SHA加密
121 | *
122 | * @param data 明文字节数组
123 | * @return 密文字节数组
124 | */
125 | public static byte[] encryptSHA(byte[] data) {
126 | try {
127 | MessageDigest md = MessageDigest.getInstance("SHA");
128 | md.update(data);
129 | return md.digest();
130 | } catch (NoSuchAlgorithmException e) {
131 | e.printStackTrace();
132 | }
133 | return new byte[0];
134 | }
135 |
136 | /**
137 | * 一个byte转为2个hex字符
138 | */
139 | public static String bytes2Hex(byte[] src) {
140 | char[] res = new char[src.length * 2];
141 | final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
142 | for (int i = 0, j = 0; i < src.length; i++) {
143 | res[j++] = hexDigits[src[i] >>> 4 & 0x0f];
144 | res[j++] = hexDigits[src[i] & 0x0f];
145 | }
146 | return new String(res);
147 | }
148 | ```
149 |
--------------------------------------------------------------------------------
/about_keyboard.md:
--------------------------------------------------------------------------------
1 | # 键盘相关
2 | ### 避免输入法面板遮挡
3 | ``` java
4 | // 在manifest.xml中activity中设置
5 | android:windowSoftInputMode="stateVisible|adjustResize"
6 | ```
7 |
8 | ### 动态隐藏软键盘
9 | ``` java
10 | /**
11 | * 动态隐藏软键盘
12 | */
13 | public static void hideSoftInput(Activity activity) {
14 | View view = activity.getWindow().peekDecorView();
15 | if (view != null) {
16 | InputMethodManager inputmanger = (InputMethodManager) activity
17 | .getSystemService(Context.INPUT_METHOD_SERVICE);
18 | inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
19 | }
20 | }
21 |
22 | /**
23 | * 动态隐藏软键盘
24 | */
25 | public static void hideSoftInput(Context context, EditText edit) {
26 | edit.clearFocus();
27 | InputMethodManager inputmanger = (InputMethodManager) context
28 | .getSystemService(Context.INPUT_METHOD_SERVICE);
29 | inputmanger.hideSoftInputFromWindow(edit.getWindowToken(), 0);
30 | }
31 | ```
32 |
33 | ### 点击屏幕空白区域隐藏软键盘
34 | ``` java
35 | /**
36 | * 点击屏幕空白区域隐藏软键盘(方法0)
37 | * 在onTouch中处理,未获焦点则隐藏
38 | * 参照以下注释代码
39 | */
40 | public static void clickBlankArea2HideSoftInput0() {
41 | Log.i("tips", "U should copy the following code.");
42 | /*
43 | @Override
44 | public boolean onTouchEvent (MotionEvent event){
45 | if (null != this.getCurrentFocus()) {
46 | InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
47 | return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
48 | }
49 | return super.onTouchEvent(event);
50 | }
51 | */
52 | }
53 |
54 | /**
55 | * 点击屏幕空白区域隐藏软键盘(方法1)
56 | * 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘
57 | * 需重写dispatchTouchEvent
58 | * 参照以下注释代码
59 | */
60 | public static void clickBlankArea2HideSoftInput1() {
61 | Log.i("tips", "U should copy the following code.");
62 | /*
63 | @Override
64 | public boolean dispatchTouchEvent(MotionEvent ev) {
65 | if (ev.getAction() == MotionEvent.ACTION_DOWN) {
66 | View v = getCurrentFocus();
67 | if (isShouldHideKeyboard(v, ev)) {
68 | hideKeyboard(v.getWindowToken());
69 | }
70 | }
71 | return super.dispatchTouchEvent(ev);
72 | }
73 | // 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘
74 | private boolean isShouldHideKeyboard(View v, MotionEvent event) {
75 | if (v != null && (v instanceof EditText)) {
76 | int[] l = {0, 0};
77 | v.getLocationInWindow(l);
78 | int left = l[0],
79 | top = l[1],
80 | bottom = top + v.getHeight(),
81 | right = left + v.getWidth();
82 | return !(event.getX() > left && event.getX() < right
83 | && event.getY() > top && event.getY() < bottom);
84 | }
85 | return false;
86 | }
87 | // 获取InputMethodManager,隐藏软键盘
88 | private void hideKeyboard(IBinder token) {
89 | if (token != null) {
90 | InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
91 | im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
92 | }
93 | }
94 | */
95 | }
96 | ```
97 |
98 | ### 动态显示软键盘
99 | ``` java
100 | /**
101 | * 动态显示软键盘
102 | */
103 | public static void showSoftInput(Context context, EditText edit) {
104 | edit.setFocusable(true);
105 | edit.setFocusableInTouchMode(true);
106 | edit.requestFocus();
107 | InputMethodManager inputManager = (InputMethodManager) context
108 | .getSystemService(Context.INPUT_METHOD_SERVICE);
109 | inputManager.showSoftInput(edit, 0);
110 | }
111 | ```
112 |
113 | ### 切换键盘显示与否状态
114 | ``` java
115 | /**
116 | * 切换键盘显示与否状态
117 | */
118 | public static void toggleSoftInput(Context context, EditText edit) {
119 | edit.setFocusable(true);
120 | edit.setFocusableInTouchMode(true);
121 | edit.requestFocus();
122 | InputMethodManager inputManager = (InputMethodManager) context
123 | .getSystemService(Context.INPUT_METHOD_SERVICE);
124 | inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
125 | }
126 | ```
127 |
--------------------------------------------------------------------------------
/about_network.md:
--------------------------------------------------------------------------------
1 | # 网络相关
2 | ### 打开网络设置界面
3 | ``` java
4 | /**
5 | * 打开网络设置界面
6 | * 3.0以下打开设置界面
7 | */
8 | public static void openWirelessSettings(Context context) {
9 | if (android.os.Build.VERSION.SDK_INT > 10) {
10 | context.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
11 | } else {
12 | context.startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
13 | }
14 | }
15 | ```
16 |
17 | ### 判断网络是否可用
18 | ``` java
19 | /**
20 | * 获取活动网路信息
21 | */
22 | private static NetworkInfo getActiveNetworkInfo(Context context) {
23 | ConnectivityManager cm = (ConnectivityManager) context
24 | .getSystemService(Context.CONNECTIVITY_SERVICE);
25 | return cm.getActiveNetworkInfo();
26 | }
27 |
28 | /**
29 | * 判断网络是否可用
30 | * 需添加权限 需添加权限 需添加权限 需添加权限 如中国联通、中国移动、中国电信
80 | */
81 | public static String getNetworkOperatorName(Context context) {
82 | TelephonyManager tm = (TelephonyManager) context
83 | .getSystemService(Context.TELEPHONY_SERVICE);
84 | return tm != null ? tm.getNetworkOperatorName() : null;
85 | }
86 | ```
87 |
88 | ### 获取移动终端类型
89 | ``` java
90 | /**
91 | * 获取移动终端类型
92 | *
93 | * @return 手机制式
94 | * 需添加权限 需与上面的isPhone一起使用
18 | * 需添加权限 需添加权限 返回如下
38 | * 需添加权限 需添加权限 需添加权限 参照以下注释代码
183 | */
184 | public static void getContantNum() {
185 | Log.i("tips", "U should copy the follow code.");
186 | /*
187 | Intent intent = new Intent();
188 | intent.setAction("android.intent.action.PICK");
189 | intent.setType("vnd.android.cursor.dir/phone_v2");
190 | startActivityForResult(intent, 0);
191 | @Override
192 | protected void onActivityResult ( int requestCode, int resultCode, Intent data){
193 | super.onActivityResult(requestCode, resultCode, data);
194 | if (data != null) {
195 | Uri uri = data.getData();
196 | String num = null;
197 | // 创建内容解析者
198 | ContentResolver contentResolver = getContentResolver();
199 | Cursor cursor = contentResolver.query(uri,
200 | null, null, null, null);
201 | while (cursor.moveToNext()) {
202 | num = cursor.getString(cursor.getColumnIndex("data1"));
203 | }
204 | cursor.close();
205 | num = num.replaceAll("-", "");//替换的操作,555-6 -> 5556
206 | }
207 | }
208 | */
209 | }
210 | ```
211 |
212 | ### 获取手机短信并保存到xml中
213 | ``` java
214 | /**
215 | * 获取手机短信并保存到xml中
216 | * 需添加权限 需添加权限
26 | * 移动:134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188
27 | * 联通:130、131、132、145、155、156、175、176、185、186
28 | * 电信:133、153、173、177、180、181、189
29 | * 全球星:1349
30 | * 虚拟运营商:170
31 | */
32 | private static final String REGEX_MOBILE_EXACT = "^((13[0-9])|(14[5,7])|(15[0-3,5-8])|(17[0,3,5-8])|(18[0-9])|(147))\\d{8}$";
33 | /**
34 | * 验证座机号,正确格式:xxx/xxxx-xxxxxxx/xxxxxxxx/
35 | */
36 | private static final String REGEX_TEL = "^0\\d{2,3}[- ]?\\d{7,8}";
37 | /**
38 | * 验证邮箱
39 | */
40 | private static final String REGEX_EMAIL = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
41 | /**
42 | * 验证url
43 | */
44 | private static final String REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?";
45 | /**
46 | * 验证汉字
47 | */
48 | private static final String REGEX_CHZ = "^[\\u4e00-\\u9fa5]+$";
49 | /**
50 | * 验证用户名,取值范围为a-z,A-Z,0-9,"_",汉字,不能以"_"结尾,用户名必须是6-20位
51 | */
52 | private static final String REGEX_USERNAME = "^[\\w\\u4e00-\\u9fa5]{6,20}(?= 19方可使用)
26 | ``` java
27 | /**
28 | * 设置透明状态栏(api >= 19方可使用)
29 | * 可在Activity的onCreat()中调用
30 | * 需在顶部控件布局中加入以下属性让内容出现在状态栏之下
31 | * android:clipToPadding="true"
32 | * android:fitsSystemWindows="true"
33 | */
34 | public static void setTransparentStatusBar(Activity activity) {
35 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
36 | //透明状态栏
37 | activity.getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
38 | //透明导航栏
39 | activity.getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
40 | }
41 | }
42 | ```
43 |
44 | ### 隐藏状态栏
45 | ``` java
46 | /**
47 | * 隐藏状态栏
48 | * 也就是设置全屏,一定要在setContentView之前调用,否则报错
49 | * 此方法Activity可以继承AppCompatActivity
50 | * 启动的时候状态栏会显示一下再隐藏,比如QQ的欢迎界面
51 | * 在配置文件中Activity加属性android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
52 | * 如加了以上配置Activity不能继承AppCompatActivity,会报错
53 | */
54 | public static void hideStatusBar(Activity activity) {
55 | activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
56 | activity.getWindow().setFlags(LayoutParams.FLAG_FULLSCREEN,
57 | LayoutParams.FLAG_FULLSCREEN);
58 | }
59 | ```
60 |
61 | ### 获取状态栏高度
62 | ``` java
63 | /**
64 | * 获取状态栏高度
65 | */
66 | public static int getStatusBarHeight(Context context) {
67 | int result = 0;
68 | int resourceId = context.getResources()
69 | .getIdentifier("status_bar_height", "dimen", "android");
70 | if (resourceId > 0) {
71 | result = context.getResources().getDimensionPixelSize(resourceId);
72 | }
73 | return result;
74 | }
75 | ```
76 |
77 | ### 判断状态栏是否存在
78 | ``` java
79 | /**
80 | * 判断状态栏是否存在
81 | *
82 | * @param activity
83 | * @return 还有一种就是在Activity中加属性android:screenOrientation="landscape"
113 | * 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
114 | * 设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
115 | * 设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"(4.0以上必须带最后一个参数)时
116 | * 切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
117 | */
118 | public static void setLandscape(Activity activity) {
119 | activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
120 | }
121 | ```
122 |
123 | ### 获取当前屏幕截图
124 | ``` java
125 | /**
126 | * 获取当前屏幕截图,包含状态栏
127 | */
128 | public static Bitmap captureWithStatusBar(Activity activity) {
129 | View view = activity.getWindow().getDecorView();
130 | view.setDrawingCacheEnabled(true);
131 | view.buildDrawingCache();
132 | Bitmap bmp = view.getDrawingCache();
133 | int width = getScreenWidth(activity);
134 | int height = getScreenHeight(activity);
135 | Bitmap bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
136 | view.destroyDrawingCache();
137 | return bp;
138 | }
139 |
140 | /**
141 | * 获取当前屏幕截图,不包含状态栏
142 | * 需要用到上面获取状态栏高度的方法
143 | */
144 | public static Bitmap captureWithoutStatusBar(Activity activity) {
145 | View view = activity.getWindow().getDecorView();
146 | view.setDrawingCacheEnabled(true);
147 | view.buildDrawingCache();
148 | Bitmap bmp = view.getDrawingCache();
149 | int statusBarHeight = getStatusBarHeight(activity);
150 | int width = getScreenWidth(activity);
151 | int height = getScreenHeight(activity);
152 | Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
153 | view.destroyDrawingCache();
154 | return bp;
155 | }
156 | ```
157 |
158 | ### 判断是否锁屏
159 | ``` java
160 | /**
161 | * 判断是否锁屏
162 | */
163 | public static boolean isScreenLock(Context context) {
164 | KeyguardManager km = (KeyguardManager) context
165 | .getSystemService(Context.KEYGUARD_SERVICE);
166 | return km.inKeyguardRestrictedInputMode();
167 | }
168 | ```
169 |
170 | ***
171 | # 尺寸相关
172 | ### dp与px转换
173 | ``` java
174 | /**
175 | * dp转px
176 | */
177 | public static int dp2px(Context context, float dpValue) {
178 | final float scale = context.getResources().getDisplayMetrics().density;
179 | return (int) (dpValue * scale + 0.5f);
180 | }
181 |
182 | /**
183 | * px转dp
184 | */
185 | public static int px2dp(Context context, float pxValue) {
186 | final float scale = context.getResources().getDisplayMetrics().density;
187 | return (int) (pxValue / scale + 0.5f);
188 | }
189 | ```
190 |
--------------------------------------------------------------------------------
/about_size.md:
--------------------------------------------------------------------------------
1 | # 尺寸相关
2 | ### dp与px转换
3 | ``` java
4 | /**
5 | * dp转px
6 | */
7 | public static int dp2px(Context context, float dpValue) {
8 | final float scale = context.getResources().getDisplayMetrics().density;
9 | return (int) (dpValue * scale + 0.5f);
10 | }
11 |
12 | /**
13 | * px转dp
14 | */
15 | public static int px2dp(Context context, float pxValue) {
16 | final float scale = context.getResources().getDisplayMetrics().density;
17 | return (int) (pxValue / scale + 0.5f);
18 | }
19 | ```
20 |
21 | ### sp与px转换
22 | ``` java
23 | /**
24 | * sp转px
25 | */
26 | public static int sp2px(Context context, float spValue) {
27 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
28 | return (int) (spValue * fontScale + 0.5f);
29 | }
30 |
31 | /**
32 | * px转sp
33 | */
34 | public static int px2sp(Context context, float pxValue) {
35 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
36 | return (int) (pxValue / fontScale + 0.5f);
37 | }
38 | ```
39 |
40 | ### 各种单位转换
41 | ``` java
42 | /**
43 | * 各种单位转换
44 | * 该方法存在于TypedValue
45 | */
46 | public static float applyDimension(int unit, float value, DisplayMetrics metrics) {
47 | switch (unit) {
48 | case TypedValue.COMPLEX_UNIT_PX:
49 | return value;
50 | case TypedValue.COMPLEX_UNIT_DIP:
51 | return value * metrics.density;
52 | case TypedValue.COMPLEX_UNIT_SP:
53 | return value * metrics.scaledDensity;
54 | case TypedValue.COMPLEX_UNIT_PT:
55 | return value * metrics.xdpi * (1.0f / 72);
56 | case TypedValue.COMPLEX_UNIT_IN:
57 | return value * metrics.xdpi;
58 | case TypedValue.COMPLEX_UNIT_MM:
59 | return value * metrics.xdpi * (1.0f / 25.4f);
60 | }
61 | return 0;
62 | }
63 | ```
64 |
65 | ### 在onCreate()即可强行获取View的尺寸
66 | ``` java
67 | /**
68 | * 在onCreate()即可强行获取View的尺寸
69 | * 需回调onGetSizeListener接口,在onGetSize中获取view宽高
70 | * 用法示例如下所示
71 | * SizeUtils.forceGetViewSize(view);
72 | * SizeUtils.setListener(new SizeUtils.onGetSizeListener() {
73 | * @Override
74 | * public void onGetSize(View view) {
75 | * Log.d("tag", view.getWidth() + " " + view.getHeight());
76 | * }
77 | * });
78 | */
79 | public static void forceGetViewSize(final View view) {
80 | view.post(new Runnable() {
81 | @Override
82 | public void run() {
83 | if (mListener != null) {
84 | mListener.onGetSize(view);
85 | }
86 | }
87 | });
88 | }
89 |
90 | /**
91 | * 获取到View尺寸的监听
92 | */
93 | public interface onGetSizeListener {
94 | void onGetSize(View view);
95 | }
96 |
97 | public static void setListener(onGetSizeListener listener) {
98 | mListener = listener;
99 | }
100 |
101 | private static onGetSizeListener mListener;
102 | ```
103 |
104 | ### ListView中提前测量View尺寸
105 | ``` java
106 | /**
107 | * ListView中提前测量View尺寸,如headerView
108 | * 用的时候去掉注释拷贝到ListView中即可
109 | * 参照以下注释代码
110 | */
111 | public static void measureViewInLV(View view) {
112 | Log.i("tips", "U should copy the follow code.");
113 | /*
114 | ViewGroup.LayoutParams p = view.getLayoutParams();
115 | if (p == null) {
116 | p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
117 | ViewGroup.LayoutParams.WRAP_CONTENT);
118 | }
119 | int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
120 | int height;
121 | int tempHeight = p.height;
122 | if (tempHeight > 0) {
123 | height = MeasureSpec.makeMeasureSpec(tempHeight,
124 | MeasureSpec.EXACTLY);
125 | } else {
126 | height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
127 | }
128 | view.measure(width, height);
129 | */
130 | }
131 | ```
132 |
--------------------------------------------------------------------------------
/about_time.md:
--------------------------------------------------------------------------------
1 | # 时间相关
2 | ### 将时间戳转为时间字符串
3 | ``` java
4 | /**
5 | * 将时间戳转为时间字符串
6 | * 格式为yyyy-MM-dd HH:mm:ss
7 | */
8 | public static String milliseconds2String(long milliseconds) {
9 | return milliseconds2String(milliseconds, DEFAULT_SDF);
10 | }
11 |
12 | /**
13 | * 将时间戳转为时间字符串
14 | * 格式为用户自定义
15 | */
16 | public static String milliseconds2String(long milliseconds, SimpleDateFormat format) {
17 | return format.format(new Date(milliseconds));
18 | }
19 | ```
20 |
21 | ### 将时间字符串转为时间戳
22 | ``` java
23 | /**
24 | * 将时间字符串转为时间戳
25 | * 格式为yyyy-MM-dd HH:mm:ss
26 | */
27 | public static long string2Milliseconds(String time) {
28 | return string2Milliseconds(time, DEFAULT_SDF);
29 | }
30 |
31 | /**
32 | * 将时间字符串转为时间戳
33 | * 格式为用户自定义
34 | */
35 | public static long string2Milliseconds(String time, SimpleDateFormat format) {
36 | try {
37 | return format.parse(time).getTime();
38 | } catch (ParseException e) {
39 | e.printStackTrace();
40 | }
41 | return -1;
42 | }
43 | ```
44 |
45 | ### 将时间字符串转为Date类型
46 | ``` java
47 | /**
48 | * 将时间字符串转为Date类型
49 | * 格式为yyyy-MM-dd HH:mm:ss
50 | */
51 | public static Date string2Date(String formatDate) {
52 | return string2Date(formatDate, DEFAULT_SDF);
53 | }
54 |
55 | /**
56 | * 将时间字符串转为Date类型
57 | * 格式为用户自定义
58 | */
59 | public static Date string2Date(String formatDate, SimpleDateFormat format) {
60 | return new Date(string2Milliseconds(formatDate, format));
61 | }
62 | ```
63 |
64 | ### 将Date类型转为时间字符串
65 | ``` java
66 | /**
67 | * 将Date类型转为时间字符串
68 | * 格式为yyyy-MM-dd HH:mm:ss
69 | */
70 | public static String date2String(Date date) {
71 | return date2String(date, DEFAULT_SDF);
72 | }
73 |
74 | /**
75 | * 将Date类型转为时间字符串
76 | * 格式为用户自定义
77 | */
78 | public static String date2String(Date date, SimpleDateFormat format) {
79 | return format.format(date);
80 | }
81 | ```
82 |
83 | ### 将Date类型转为时间戳
84 | ``` java
85 | /**
86 | * 将Date类型转为时间戳
87 | */
88 | public static long date2Milliseconds(Date date) {
89 | return date.getTime();
90 | }
91 | ```
92 |
93 | ### 将时间戳转为Date类型
94 | ``` java
95 | /**
96 | * 将时间戳转为Date类型
97 | */
98 | public static Date milliseconds2Date(long milliseconds) {
99 | return new Date(milliseconds);
100 | }
101 | ```
102 |
103 | ### 毫秒时间戳单位转换(单位:unit)
104 | ``` java
105 | /**
106 | * 毫秒时间戳单位转换(单位:unit)
107 | * time1和time2格式都为yyyy-MM-dd HH:mm:ss
140 | */
141 | public static long getIntervalTime(String time1, String time2, int unit) {
142 | return getIntervalTime(time1, time2, unit, DEFAULT_SDF);
143 | }
144 |
145 | /**
146 | * 获取两个时间差(单位:unit)
147 | * time1和time2格式都为format
155 | */
156 | public static long getIntervalTime(String time1, String time2, int unit, SimpleDateFormat for
157 | return milliseconds2Unit(string2Milliseconds(time1, format)
158 | - string2Milliseconds(time2, format), unit);
159 | }
160 |
161 | /**
162 | * 获取两个时间差(单位:unit)
163 | * time1和time2都为Date
171 | */
172 | public static long getIntervalTime(Date time1, Date time2, int unit) {
173 | return milliseconds2Unit(date2Milliseconds(time2) - date2Milliseconds(time1), unit);
174 | }
175 | ```
176 |
177 | ### 获取当前时间
178 | ``` java
179 | /**
180 | * 获取当前时间
181 | * 单位(毫秒)
182 | */
183 | public static long getCurTimeMills() {
184 | return System.currentTimeMillis();
185 | }
186 |
187 | /**
188 | * 获取当前时间
189 | * 格式为yyyy-MM-dd HH:mm:ss
190 | */
191 | public static String getCurTimeString() {
192 | return milliseconds2String(getCurTimeMills());
193 | }
194 |
195 | /**
196 | * 获取当前时间
197 | * 格式为用户自定义
198 | */
199 | public static String getCurTimeString(SimpleDateFormat format) {
200 | return milliseconds2String(getCurTimeMills(), format);
201 | }
202 |
203 | /**
204 | * 获取当前时间
205 | * Date类型
206 | */
207 | public static Date getCurTimeDate() {
208 | return new Date();
209 | }
210 | ```
211 |
212 | ### 获取与当前时间的差(单位:unit)
213 | ``` java
214 | /**
215 | * 获取与当前时间的差(单位:unit)
216 | * time1和time2格式都为yyyy-MM-dd HH:mm:ss
223 | */
224 | public static long getIntervalByNow(String time, int unit) {
225 | return getIntervalByNow(time, unit, DEFAULT_SDF);
226 | }
227 |
228 | /**
229 | * 获取与当前时间的差(单位:unit)
230 | * time1和time2格式都为format
237 | */
238 | public static long getIntervalByNow(String time, int unit, SimpleDateFormat format) {
239 | return getIntervalTime(getCurTimeString(), time, unit, format);
240 | }
241 |
242 | /**
243 | * 获取与当前时间的差(单位:unit)
244 | * time1和time2格式都为format
251 | */
252 | public static long getIntervalByNow(Date time, int unit) {
253 | return getIntervalTime(getCurTimeDate(), time, unit);
254 | }
255 | ```
256 |
257 | ### 判断闰年
258 | ``` java
259 | /**
260 | * 判断闰年
261 | */
262 | public static boolean isLeapYear(int year) {
263 | return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
264 | }
265 | ```
266 |
--------------------------------------------------------------------------------
/about_unclassified.md:
--------------------------------------------------------------------------------
1 | # 未归类
2 | ### 获取服务是否开启
3 | ```
4 | /**
5 | * 获取服务是否开启
6 | * @param className 完整包名的服务类名
7 | */
8 | public static boolean isRunningService(String className, Context context) {
9 | // 进程的管理者,活动的管理者
10 | ActivityManager activityManager = (ActivityManager)
11 | context.getSystemService(Context.ACTIVITY_SERVICE);
12 | // 获取正在运行的服务,最多获取1000个
13 | List 根据路径名是否符合和文件是否存在判断是否安装成功
32 | * 更好的做法应该是startActivityForResult回调判断是否安装成功比较妥当
33 | * 这里做不了回调,后续自己做处理
34 | */
35 | public static boolean installApp(Context context, String filePath) {
36 | if (filePath != null && filePath.length() > 4
37 | && filePath.toLowerCase().substring(filePath.length() - 4).equals(".apk")) {
38 | Intent intent = new Intent(Intent.ACTION_VIEW);
39 | File file = new File(filePath);
40 | if (file.exists() && file.isFile() && file.length() > 0) {
41 | intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
42 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
43 | context.startActivity(intent);
44 | return true;
45 | }
46 | }
47 | return false;
48 | }
49 |
50 | /**
51 | * 卸载指定包名的App
52 | * 这里卸载成不成功只判断了packageName是否为空
53 | * 如果要根据是否卸载成功应该用startActivityForResult回调判断是否还存在比较妥当
54 | * 这里做不了回调,后续自己做处理
55 | */
56 | public boolean uninstallApp(Context context, String packageName) {
57 | if (!TextUtils.isEmpty(packageName)) {
58 | Intent intent = new Intent(Intent.ACTION_DELETE);
59 | intent.setData(Uri.parse("package:" + packageName));
60 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
61 | context.startActivity(intent);
62 | return true;
63 | }
64 | return false;
65 | }
66 |
67 | /**
68 | * 封装App信息的Bean类
69 | */
70 | public static class AppInfo {
71 |
72 | private String name;
73 | private Drawable icon;
74 | private String packagName;
75 | private String versionName;
76 | private int versionCode;
77 | private boolean isSD;
78 | private boolean isUser;
79 |
80 | public Drawable getIcon() {
81 | return icon;
82 | }
83 |
84 | public void setIcon(Drawable icon) {
85 | this.icon = icon;
86 | }
87 |
88 | public boolean isSD() {
89 | return isSD;
90 | }
91 |
92 | public void setSD(boolean SD) {
93 | isSD = SD;
94 | }
95 |
96 | public boolean isUser() {
97 | return isUser;
98 | }
99 |
100 | public void setUser(boolean user) {
101 | isUser = user;
102 | }
103 |
104 | public String getName() {
105 | return name;
106 | }
107 |
108 | public void setName(String name) {
109 | this.name = name;
110 | }
111 |
112 | public String getPackagName() {
113 | return packagName;
114 | }
115 |
116 | public void setPackagName(String packagName) {
117 | this.packagName = packagName;
118 | }
119 |
120 | public int getVersionCode() {
121 | return versionCode;
122 | }
123 |
124 | public void setVersionCode(int versionCode) {
125 | this.versionCode = versionCode;
126 | }
127 |
128 | public String getVersionName() {
129 | return versionName;
130 | }
131 |
132 | public void setVersionName(String versionName) {
133 | this.versionName = versionName;
134 | }
135 |
136 | /**
137 | * @param name 名称
138 | * @param icon 图标
139 | * @param packagName 包名
140 | * @param versionName 版本号
141 | * @param versionCode 版本Code
142 | * @param isSD 是否安装在SD卡
143 | * @param isUser 是否是用户程序
144 | */
145 | public AppInfo(String name, Drawable icon, String packagName,
146 | String versionName, int versionCode, boolean isSD, boolean isUser) {
147 | this.setName(name);
148 | this.setIcon(icon);
149 | this.setPackagName(packagName);
150 | this.setVersionName(versionName);
151 | this.setVersionCode(versionCode);
152 | this.setSD(isSD);
153 | this.setUser(isUser);
154 | }
155 |
156 | /*@Override
157 | public String toString() {
158 | return getName() + "\n"
159 | + getIcon() + "\n"
160 | + getPackagName() + "\n"
161 | + getVersionName() + "\n"
162 | + getVersionCode() + "\n"
163 | + isSD() + "\n"
164 | + isUser() + "\n";
165 | }*/
166 | }
167 |
168 | /**
169 | * 获取当前App信息
170 | * AppInfo(名称,图标,包名,版本号,版本Code,是否安装在SD卡,是否是用户程序)
171 | */
172 | public static AppInfo getAppInfo(Context context) {
173 | PackageManager pm = context.getPackageManager();
174 | PackageInfo pi = null;
175 | try {
176 | pi = pm.getPackageInfo(context.getApplicationContext().getPackageName(), 0);
177 | } catch (PackageManager.NameNotFoundException e) {
178 | e.printStackTrace();
179 | }
180 | return pi != null ? getBean(pm, pi) : null;
181 | }
182 |
183 | /**
184 | * 得到AppInfo的Bean
185 | */
186 | private static AppInfo getBean(PackageManager pm, PackageInfo pi) {
187 | ApplicationInfo ai = pi.applicationInfo;
188 | String name = ai.loadLabel(pm).toString();
189 | Drawable icon = ai.loadIcon(pm);
190 | String packageName = pi.packageName;
191 | String versionName = pi.versionName;
192 | int versionCode = pi.versionCode;
193 | boolean isSD = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != ApplicationInfo.FLAG_SYSTEM;
194 | boolean isUser = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != ApplicationInfo.FLAG_SYSTEM;
195 | return new AppInfo(name, icon, packageName, versionName, versionCode, isSD, isUser);
196 | }
197 |
198 | /**
199 | * 获取所有已安装App信息
200 | * AppInfo(名称,图标,包名,版本号,版本Code,是否安装在SD卡,是否是用户程序)
201 | * 依赖上面的getBean方法
202 | */
203 | public static List 需添加 并且必须是系统应用该方法才有效
261 | */
262 | public static boolean isAppBackground(Context context) {
263 | ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
264 | @SuppressWarnings("deprecation")
265 | List 需添加权限 一般是/storage/emulated/0/
70 | */
71 | public static String getSDCardPath() {
72 | return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/utilcode/src/main/java/com/blankj/utilcode/utils/EncryptUtils.java:
--------------------------------------------------------------------------------
1 | package com.blankj.utilcode.utils;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.IOException;
6 | import java.nio.MappedByteBuffer;
7 | import java.nio.channels.FileChannel;
8 | import java.security.MessageDigest;
9 | import java.security.NoSuchAlgorithmException;
10 |
11 | /*********************************************
12 | * author: Blankj on 2016/8/2 21:22
13 | * blog: http://blankj.com
14 | * e-mail: blankj@qq.com
15 | *********************************************/
16 | public class EncryptUtils {
17 |
18 | private EncryptUtils() {
19 | throw new UnsupportedOperationException("u can't fuck me...");
20 | }
21 |
22 | /**
23 | * MD5加密
24 | *
25 | * @param data 明文字符串
26 | * @return 密文
27 | */
28 | public static String getMD5(String data) {
29 | return getMD5(data.getBytes());
30 | }
31 |
32 | /**
33 | * MD5加密
34 | *
35 | * @param data 明文字符串
36 | * @param salt 盐
37 | * @return 密文
38 | */
39 | public static String getMD5(String data, String salt) {
40 | return bytes2Hex(encryptMD5((data + salt).getBytes()));
41 | }
42 |
43 | /**
44 | * MD5加密
45 | *
46 | * @param data 明文字节数组
47 | * @return 密文
48 | */
49 | public static String getMD5(byte[] data) {
50 | return bytes2Hex(encryptMD5(data));
51 | }
52 |
53 | /**
54 | * MD5加密
55 | *
56 | * @param data 明文字节数组
57 | * @param salt 盐字节数组
58 | * @return 密文
59 | */
60 | public static String getMD5(byte[] data, byte[] salt) {
61 | byte[] dataSalt = new byte[data.length + salt.length];
62 | System.arraycopy(data, 0, dataSalt, 0, data.length);
63 | System.arraycopy(salt, 0, dataSalt, data.length, salt.length);
64 | return bytes2Hex(encryptMD5(dataSalt));
65 | }
66 |
67 | /**
68 | * MD5加密
69 | *
70 | * @param data 明文字节数组
71 | * @return 密文字节数组
72 | */
73 | public static byte[] encryptMD5(byte[] data) {
74 | try {
75 | MessageDigest md = MessageDigest.getInstance("MD5");
76 | md.update(data);
77 | return md.digest();
78 | } catch (NoSuchAlgorithmException e) {
79 | e.printStackTrace();
80 | }
81 | return new byte[0];
82 | }
83 |
84 | /**
85 | * 获取文件的MD5校验码
86 | *
87 | * @param filePath 文件路径
88 | * @return 文件的MD5校验码
89 | */
90 | public static String getMD5File(String filePath) {
91 | return getMD5File(new File(filePath));
92 | }
93 |
94 | /**
95 | * 获取文件的MD5校验码
96 | *
97 | * @param file 文件
98 | * @return 文件的MD5校验码
99 | */
100 | public static String getMD5File(File file) {
101 | FileInputStream in = null;
102 | try {
103 | in = new FileInputStream(file);
104 | FileChannel channel = in.getChannel();
105 | MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
106 | MessageDigest md = MessageDigest.getInstance("MD5");
107 | md.update(buffer);
108 | return bytes2Hex(md.digest());
109 | } catch (NoSuchAlgorithmException | IOException e) {
110 | e.printStackTrace();
111 | } finally {
112 | if (in != null) {
113 | try {
114 | in.close();
115 | } catch (IOException ignored) {
116 | }
117 | }
118 | }
119 | return "";
120 | }
121 |
122 | /**
123 | * SHA加密
124 | *
125 | * @param data 明文字符串
126 | * @return 密文
127 | */
128 | public static String getSHA(String data) {
129 | return getSHA(data.getBytes());
130 | }
131 |
132 | /**
133 | * SHA加密
134 | *
135 | * @param data 明文字节数组
136 | * @return 密文
137 | */
138 | public static String getSHA(byte[] data) {
139 | return bytes2Hex(encryptSHA(data));
140 | }
141 |
142 | /**
143 | * SHA加密
144 | *
145 | * @param data 明文字节数组
146 | * @return 密文字节数组
147 | */
148 | public static byte[] encryptSHA(byte[] data) {
149 | try {
150 | MessageDigest md = MessageDigest.getInstance("SHA");
151 | md.update(data);
152 | return md.digest();
153 | } catch (NoSuchAlgorithmException e) {
154 | e.printStackTrace();
155 | }
156 | return new byte[0];
157 | }
158 |
159 | /**
160 | * 一个byte转为2个hex字符
161 | */
162 | public static String bytes2Hex(byte[] src) {
163 | char[] res = new char[src.length * 2];
164 | final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
165 | for (int i = 0, j = 0; i < src.length; i++) {
166 | res[j++] = hexDigits[src[i] >>> 4 & 0x0f];
167 | res[j++] = hexDigits[src[i] & 0x0f];
168 | }
169 | return new String(res);
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/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 | * author: Blankj on 2016/8/2 21:18
12 | * blog: http://blankj.com
13 | * e-mail: blankj@qq.com
14 | *********************************************/
15 | public class KeyboardUtils {
16 |
17 | private KeyboardUtils() {
18 | throw new UnsupportedOperationException("u can't fuck me...");
19 | }
20 |
21 | /**
22 | * 动态隐藏软键盘
23 | */
24 | public static void hideSoftInput(Activity activity) {
25 | View view = activity.getWindow().peekDecorView();
26 | if (view != null) {
27 | InputMethodManager inputmanger = (InputMethodManager) activity
28 | .getSystemService(Context.INPUT_METHOD_SERVICE);
29 | inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
30 | }
31 | }
32 |
33 | /**
34 | * 动态隐藏软键盘
35 | */
36 | public static void hideSoftInput(Context context, EditText edit) {
37 | edit.clearFocus();
38 | InputMethodManager inputmanger = (InputMethodManager) context
39 | .getSystemService(Context.INPUT_METHOD_SERVICE);
40 | inputmanger.hideSoftInputFromWindow(edit.getWindowToken(), 0);
41 | }
42 |
43 | /**
44 | * 点击屏幕空白区域隐藏软键盘(方法1)
45 | * 在onTouch中处理,未获焦点则隐藏
46 | * 参照以下注释代码
47 | */
48 | public static void clickBlankArea2HideSoftInput0() {
49 | Log.i("tips", "U should copy the following code.");
50 | /*
51 | @Override
52 | public boolean onTouchEvent (MotionEvent event){
53 | if (null != this.getCurrentFocus()) {
54 | InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
55 | return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
56 | }
57 | return super.onTouchEvent(event);
58 | }
59 | */
60 | }
61 |
62 | /**
63 | * 点击屏幕空白区域隐藏软键盘(方法2)
64 | * 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘
65 | * 需重写dispatchTouchEvent
66 | * 参照以下注释代码
67 | */
68 | public static void clickBlankArea2HideSoftInput1() {
69 | Log.i("tips", "U should copy the following code.");
70 | /*
71 | @Override
72 | public boolean dispatchTouchEvent(MotionEvent ev) {
73 | if (ev.getAction() == MotionEvent.ACTION_DOWN) {
74 | View v = getCurrentFocus();
75 | if (isShouldHideKeyboard(v, ev)) {
76 | hideKeyboard(v.getWindowToken());
77 | }
78 | }
79 | return super.dispatchTouchEvent(ev);
80 | }
81 |
82 | // 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘
83 | private boolean isShouldHideKeyboard(View v, MotionEvent event) {
84 | if (v != null && (v instanceof EditText)) {
85 | int[] l = {0, 0};
86 | v.getLocationInWindow(l);
87 | int left = l[0],
88 | top = l[1],
89 | bottom = top + v.getHeight(),
90 | right = left + v.getWidth();
91 | return !(event.getX() > left && event.getX() < right
92 | && event.getY() > top && event.getY() < bottom);
93 | }
94 | return false;
95 | }
96 |
97 | // 获取InputMethodManager,隐藏软键盘
98 | private void hideKeyboard(IBinder token) {
99 | if (token != null) {
100 | InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
101 | im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
102 | }
103 | }
104 | */
105 | }
106 |
107 | /**
108 | * 动态显示软键盘
109 | */
110 | public static void showSoftInput(Context context, EditText edit) {
111 | edit.setFocusable(true);
112 | edit.setFocusableInTouchMode(true);
113 | edit.requestFocus();
114 | InputMethodManager inputManager = (InputMethodManager) context
115 | .getSystemService(Context.INPUT_METHOD_SERVICE);
116 | inputManager.showSoftInput(edit, 0);
117 | }
118 |
119 | /**
120 | * 切换键盘显示与否状态
121 | */
122 | public static void toggleSoftInput(Context context, EditText edit) {
123 | edit.setFocusable(true);
124 | edit.setFocusableInTouchMode(true);
125 | edit.requestFocus();
126 | InputMethodManager inputManager = (InputMethodManager) context
127 | .getSystemService(Context.INPUT_METHOD_SERVICE);
128 | inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/utilcode/src/main/java/com/blankj/utilcode/utils/NetworkUtils.java:
--------------------------------------------------------------------------------
1 | package com.blankj.utilcode.utils;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.net.ConnectivityManager;
7 | import android.net.NetworkInfo;
8 | import android.telephony.TelephonyManager;
9 |
10 | /*********************************************
11 | * author: Blankj on 2016/8/1 21:33
12 | * blog: http://blankj.com
13 | * e-mail: blankj@qq.com
14 | *********************************************/
15 | public class NetworkUtils {
16 |
17 | private NetworkUtils() {
18 | throw new UnsupportedOperationException("u can't fuck me...");
19 | }
20 |
21 | /**
22 | * 打开网络设置界面
23 | * 3.0以下打开设置界面
24 | */
25 | public static void openWirelessSettings(Context context) {
26 | if (android.os.Build.VERSION.SDK_INT > 10) {
27 | context.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
28 | } else {
29 | context.startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
30 | }
31 | }
32 |
33 | /**
34 | * 判断是否网络连接
35 | * 需添加权限 需添加权限 如中国联通、中国移动、中国电信
57 | */
58 | public static String getNetworkOperatorName(Context context) {
59 | TelephonyManager tm = (TelephonyManager) context
60 | .getSystemService(Context.TELEPHONY_SERVICE);
61 | return tm != null ? tm.getNetworkOperatorName() : null;
62 | }
63 |
64 | /**
65 | * 获取移动终端类型
66 | * 联通的3G为UMTS或HSDPA,移动和联通的2G为GPRS或EGDE,电信的2G为CDMA,电信的3G为EVDO
82 | */
83 | public static int getNetworkTpye(Context context) {
84 | TelephonyManager tm = (TelephonyManager) context
85 | .getSystemService(Context.TELEPHONY_SERVICE);
86 | switch (tm.getNetworkType()) {
87 | case TelephonyManager.NETWORK_TYPE_GPRS:
88 | case TelephonyManager.NETWORK_TYPE_EDGE:
89 | case TelephonyManager.NETWORK_TYPE_CDMA:
90 | case TelephonyManager.NETWORK_TYPE_1xRTT:
91 | case TelephonyManager.NETWORK_TYPE_IDEN:
92 | return Constants.NETWORK_CLASS_2_G;
93 | case TelephonyManager.NETWORK_TYPE_UMTS:
94 | case TelephonyManager.NETWORK_TYPE_EVDO_0:
95 | case TelephonyManager.NETWORK_TYPE_EVDO_A:
96 | case TelephonyManager.NETWORK_TYPE_HSDPA:
97 | case TelephonyManager.NETWORK_TYPE_HSUPA:
98 | case TelephonyManager.NETWORK_TYPE_HSPA:
99 | case TelephonyManager.NETWORK_TYPE_EVDO_B:
100 | case TelephonyManager.NETWORK_TYPE_EHRPD:
101 | case TelephonyManager.NETWORK_TYPE_HSPAP:
102 | return Constants.NETWORK_CLASS_3_G;
103 | case TelephonyManager.NETWORK_TYPE_LTE:
104 | return Constants.NETWORK_CLASS_4_G;
105 | default:
106 | return Constants.NETWORK_CLASS_UNKNOWN;
107 | }
108 | }
109 |
110 | public class Constants {
111 | // Unknown network class
112 | public static final int NETWORK_CLASS_UNKNOWN = 0;
113 | // wifi network
114 | public static final int NETWORK_WIFI = 1;
115 | // "2G" networks
116 | public static final int NETWORK_CLASS_2_G = 2;
117 | // "3G" networks
118 | public static final int NETWORK_CLASS_3_G = 3;
119 | // "4G" networks
120 | public static final int NETWORK_CLASS_4_G = 4;
121 | }
122 |
123 | /**
124 | * 获取当前手机的网络类型(WIFI,2G,3G,4G)
125 | * 需添加权限 需要用到上面的方法
127 | */
128 | public static int getCurNetworkType(Context context) {
129 | int netWorkType = Constants.NETWORK_CLASS_UNKNOWN;
130 | ConnectivityManager cm = (ConnectivityManager) context
131 | .getSystemService(Context.CONNECTIVITY_SERVICE);
132 | NetworkInfo networkInfo = cm.getActiveNetworkInfo();
133 | if (networkInfo != null && networkInfo.isConnected()) {
134 | int type = networkInfo.getType();
135 | if (type == ConnectivityManager.TYPE_WIFI) {
136 | netWorkType = Constants.NETWORK_WIFI;
137 | } else if (type == ConnectivityManager.TYPE_MOBILE) {
138 | netWorkType = getNetworkTpye(context);
139 | }
140 | }
141 | return netWorkType;
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/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.text.TextUtils;
12 | import android.util.Log;
13 | import android.util.Xml;
14 |
15 | import org.xmlpull.v1.XmlSerializer;
16 |
17 | import java.io.File;
18 | import java.io.FileOutputStream;
19 | import java.util.ArrayList;
20 | import java.util.HashMap;
21 | import java.util.List;
22 |
23 | /*********************************************
24 | * author: Blankj on 2016/8/1 19:57
25 | * blog: http://blankj.com
26 | * e-mail: blankj@qq.com
27 | *********************************************/
28 | public class PhoneUtils {
29 |
30 | private PhoneUtils() {
31 | throw new UnsupportedOperationException("u can't fuck me...");
32 | }
33 |
34 | /**
35 | * 判断设备是否是手机
36 | */
37 | public static boolean isPhone(Context context) {
38 | TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
39 | return tm.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
40 | }
41 |
42 | /**
43 | * 获取当前设备的IMIE
44 | * 需与上面的isPhone一起使用
45 | * 需添加权限 需添加权限 返回如下
62 | * 需添加权限 需添加权限 需添加权限 参照以下注释代码
192 | */
193 | public static void getContantNum() {
194 | Log.i("tips", "U should copy the following code.");
195 | /*
196 | Intent intent = new Intent();
197 | intent.setAction("android.intent.action.PICK");
198 | intent.setType("vnd.android.cursor.dir/phone_v2");
199 | startActivityForResult(intent, 0);
200 |
201 | @Override
202 | protected void onActivityResult ( int requestCode, int resultCode, Intent data){
203 | super.onActivityResult(requestCode, resultCode, data);
204 | if (data != null) {
205 | Uri uri = data.getData();
206 | String num = null;
207 | // 创建内容解析者
208 | ContentResolver contentResolver = getContentResolver();
209 | Cursor cursor = contentResolver.query(uri,
210 | null, null, null, null);
211 | while (cursor.moveToNext()) {
212 | num = cursor.getString(cursor.getColumnIndex("data1"));
213 | }
214 | cursor.close();
215 | num = num.replaceAll("-", "");//替换的操作,555-6 -> 5556
216 | }
217 | }
218 | */
219 | }
220 |
221 | /**
222 | * 获取手机短信并保存到xml中
223 | * 需添加权限 需添加权限
25 | * 移动:134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188
26 | * 联通:130、131、132、145、155、156、175、176、185、186
27 | * 电信:133、153、173、177、180、181、189
28 | * 全球星:1349
29 | * 虚拟运营商:170
30 | */
31 | private static final String REGEX_MOBILE_EXACT = "^((13[0-9])|(14[5,7])|(15[0-3,5-8])|(17[0,3,5-8])|(18[0-9])|(147))\\d{8}$";
32 | /**
33 | * 验证座机号,正确格式:xxx/xxxx-xxxxxxx/xxxxxxxx/
34 | */
35 | private static final String REGEX_TEL = "^0\\d{2,3}[- ]?\\d{7,8}";
36 | /**
37 | * 验证邮箱
38 | */
39 | private static final String REGEX_EMAIL = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
40 | /**
41 | * 验证url
42 | */
43 | private static final String REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?";
44 | /**
45 | * 验证汉字
46 | */
47 | private static final String REGEX_CHZ = "^[\\u4e00-\\u9fa5]+$";
48 | /**
49 | * 验证用户名,取值范围为a-z,A-Z,0-9,"_",汉字,不能以"_"结尾,用户名必须是6-20位
50 | */
51 | private static final String REGEX_USERNAME = "^[\\w\\u4e00-\\u9fa5]{6,20}(?= 19方可使用)
49 | * 可在Activity的onCreat()中调用
50 | * 需在顶部控件布局中加入以下属性让内容出现在状态栏之下
51 | * android:clipToPadding="true"
52 | * android:fitsSystemWindows="true"
53 | */
54 | public static void setTransparentStatusBar(Activity activity) {
55 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
56 | //透明状态栏
57 | activity.getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
58 | //透明导航栏
59 | activity.getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
60 | }
61 | }
62 |
63 | /**
64 | * 隐藏状态栏
65 | * 也就是设置全屏,一定要在setContentView之前调用,否则报错
66 | * 此方法Activity可以继承AppCompatActivity
67 | * 启动的时候状态栏会显示一下再隐藏,比如QQ的欢迎界面
68 | * 在配置文件中Activity加属性android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
69 | * 如加了以上配置Activity不能继承AppCompatActivity,会报错
70 | */
71 | public static void hideStatusBar(Activity activity) {
72 | activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
73 | activity.getWindow().setFlags(LayoutParams.FLAG_FULLSCREEN,
74 | LayoutParams.FLAG_FULLSCREEN);
75 | }
76 |
77 | /**
78 | * 获取状态栏高度
79 | */
80 | public static int getStatusBarHeight(Context context) {
81 | int result = 0;
82 | int resourceId = context.getResources()
83 | .getIdentifier("status_bar_height", "dimen", "android");
84 | if (resourceId > 0) {
85 | result = context.getResources().getDimensionPixelSize(resourceId);
86 | }
87 | return result;
88 | }
89 |
90 | /**
91 | * 判断状态栏是否存在
92 | *
93 | * @param activity
94 | * @return 还有一种就是在Activity中加属性android:screenOrientation="landscape"
118 | * 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
119 | * 设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
120 | * 设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"(4.0以上必须带最后一个参数)时
121 | * 切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
122 | */
123 | public static void setLandscape(Activity activity) {
124 | activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
125 | }
126 |
127 | /**
128 | * 获取当前屏幕截图,包含状态栏
129 | */
130 | public static Bitmap captureWithStatusBar(Activity activity) {
131 | View view = activity.getWindow().getDecorView();
132 | view.setDrawingCacheEnabled(true);
133 | view.buildDrawingCache();
134 | Bitmap bmp = view.getDrawingCache();
135 | int width = getScreenWidth(activity);
136 | int height = getScreenHeight(activity);
137 | Bitmap bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
138 | view.destroyDrawingCache();
139 | return bp;
140 | }
141 |
142 | /**
143 | * 获取当前屏幕截图,不包含状态栏
144 | * 需要用到上面获取状态栏高度的方法
145 | */
146 | public static Bitmap captureWithoutStatusBar(Activity activity) {
147 | View view = activity.getWindow().getDecorView();
148 | view.setDrawingCacheEnabled(true);
149 | view.buildDrawingCache();
150 | Bitmap bmp = view.getDrawingCache();
151 | int statusBarHeight = getStatusBarHeight(activity);
152 | int width = getScreenWidth(activity);
153 | int height = getScreenHeight(activity);
154 | Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
155 | view.destroyDrawingCache();
156 | return bp;
157 | }
158 |
159 | /**
160 | * 判断是否锁屏
161 | */
162 | public static boolean isScreenLock(Context context) {
163 | KeyguardManager km = (KeyguardManager) context
164 | .getSystemService(Context.KEYGUARD_SERVICE);
165 | return km.inKeyguardRestrictedInputMode();
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/utilcode/src/main/java/com/blankj/utilcode/utils/SizeUtils.java:
--------------------------------------------------------------------------------
1 | package com.blankj.utilcode.utils;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.util.Log;
6 | import android.util.TypedValue;
7 | import android.view.View;
8 |
9 | /*********************************************
10 | * author: Blankj on 2016/8/1 19:12
11 | * blog: http://blankj.com
12 | * e-mail: blankj@qq.com
13 | *********************************************/
14 | public class SizeUtils {
15 |
16 | private SizeUtils() {
17 | throw new UnsupportedOperationException("u can't fuck me...");
18 | }
19 |
20 | /**
21 | * dp转px
22 | */
23 | public static int dp2px(Context context, float dpValue) {
24 | final float scale = context.getResources().getDisplayMetrics().density;
25 | return (int) (dpValue * scale + 0.5f);
26 | }
27 |
28 | /**
29 | * px转dp
30 | */
31 | public static int px2dp(Context context, float pxValue) {
32 | final float scale = context.getResources().getDisplayMetrics().density;
33 | return (int) (pxValue / scale + 0.5f);
34 | }
35 |
36 | /**
37 | * sp转px
38 | */
39 | public static int sp2px(Context context, float spValue) {
40 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
41 | return (int) (spValue * fontScale + 0.5f);
42 | }
43 |
44 | /**
45 | * px转sp
46 | */
47 | public static int px2sp(Context context, float pxValue) {
48 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
49 | return (int) (pxValue / fontScale + 0.5f);
50 | }
51 |
52 | /**
53 | * 各种单位转换
54 | * 该方法存在于TypedValue
55 | */
56 | public static float applyDimension(int unit, float value, DisplayMetrics metrics) {
57 | switch (unit) {
58 | case TypedValue.COMPLEX_UNIT_PX:
59 | return value;
60 | case TypedValue.COMPLEX_UNIT_DIP:
61 | return value * metrics.density;
62 | case TypedValue.COMPLEX_UNIT_SP:
63 | return value * metrics.scaledDensity;
64 | case TypedValue.COMPLEX_UNIT_PT:
65 | return value * metrics.xdpi * (1.0f / 72);
66 | case TypedValue.COMPLEX_UNIT_IN:
67 | return value * metrics.xdpi;
68 | case TypedValue.COMPLEX_UNIT_MM:
69 | return value * metrics.xdpi * (1.0f / 25.4f);
70 | }
71 | return 0;
72 | }
73 |
74 | /**
75 | * 在onCreate()即可强行获取View的尺寸
76 | * 需回调onGetSizeListener接口,在onGetSize中获取view宽高
77 | * 用法示例如下所示
78 | * SizeUtils.forceGetViewSize(view);
79 | * SizeUtils.setListener(new SizeUtils.onGetSizeListener() {
80 | * @Override
81 | * public void onGetSize(View view) {
82 | * Log.d("tag", view.getWidth() + " " + view.getHeight());
83 | * }
84 | * });
85 | */
86 | public static void forceGetViewSize(final View view) {
87 | view.post(new Runnable() {
88 | @Override
89 | public void run() {
90 | if (mListener != null) {
91 | mListener.onGetSize(view);
92 | }
93 | }
94 | });
95 | }
96 |
97 | /**
98 | * 获取到View尺寸的监听
99 | */
100 | public interface onGetSizeListener {
101 | void onGetSize(View view);
102 | }
103 | public static void setListener(onGetSizeListener listener) {
104 | mListener = listener;
105 | }
106 | private static onGetSizeListener mListener;
107 |
108 | /**
109 | * ListView中提前测量View尺寸,如headerView
110 | * 用的时候去掉注释拷贝到ListView中即可
111 | * 参照以下注释代码
112 | */
113 | public static void measureViewInLV(View view) {
114 | Log.i("tips", "U should copy the following code.");
115 | /*
116 | ViewGroup.LayoutParams p = view.getLayoutParams();
117 | if (p == null) {
118 | p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
119 | ViewGroup.LayoutParams.WRAP_CONTENT);
120 | }
121 | int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
122 | int height;
123 | int tempHeight = p.height;
124 | if (tempHeight > 0) {
125 | height = MeasureSpec.makeMeasureSpec(tempHeight,
126 | MeasureSpec.EXACTLY);
127 | } else {
128 | height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
129 | }
130 | view.measure(width, height);
131 | */
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/utilcode/src/main/java/com/blankj/utilcode/utils/TimeUtils.java:
--------------------------------------------------------------------------------
1 | package com.blankj.utilcode.utils;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 |
7 | /*********************************************
8 | * author: Blankj on 2016/8/3 20:25
9 | * blog: http://blankj.com
10 | * e-mail: blankj@qq.com
11 | *********************************************/
12 | public class TimeUtils {
13 |
14 | private TimeUtils() {
15 | throw new UnsupportedOperationException("u can't fuck me...");
16 | }
17 |
18 | /**
19 | * 格式为yyyy-MM-dd HH:mm:ss
78 | */
79 | public static String milliseconds2String(long milliseconds) {
80 | return milliseconds2String(milliseconds, DEFAULT_SDF);
81 | }
82 |
83 | /**
84 | * 将时间戳转为时间字符串
85 | * 格式为用户自定义
86 | */
87 | public static String milliseconds2String(long milliseconds, SimpleDateFormat format) {
88 | return format.format(new Date(milliseconds));
89 | }
90 |
91 | /**
92 | * 将时间字符串转为时间戳
93 | * 格式为yyyy-MM-dd HH:mm:ss
94 | */
95 | public static long string2Milliseconds(String time) {
96 | return string2Milliseconds(time, DEFAULT_SDF);
97 | }
98 |
99 | /**
100 | * 将时间字符串转为时间戳
101 | * 格式为用户自定义
102 | */
103 | public static long string2Milliseconds(String time, SimpleDateFormat format) {
104 | try {
105 | return format.parse(time).getTime();
106 | } catch (ParseException e) {
107 | e.printStackTrace();
108 | }
109 | return -1;
110 | }
111 |
112 | /**
113 | * 将时间字符串转为Date类型
114 | * 格式为yyyy-MM-dd HH:mm:ss
115 | */
116 | public static Date string2Date(String formatDate) {
117 | return string2Date(formatDate, DEFAULT_SDF);
118 | }
119 |
120 | /**
121 | * 将时间字符串转为Date类型
122 | * 格式为用户自定义
123 | */
124 | public static Date string2Date(String formatDate, SimpleDateFormat format) {
125 | return new Date(string2Milliseconds(formatDate, format));
126 | }
127 |
128 | /**
129 | * 将Date类型转为时间字符串
130 | * 格式为yyyy-MM-dd HH:mm:ss
131 | */
132 | public static String date2String(Date date) {
133 | return date2String(date, DEFAULT_SDF);
134 | }
135 |
136 | /**
137 | * 将Date类型转为时间字符串
138 | * 格式为用户自定义
139 | */
140 | public static String date2String(Date date, SimpleDateFormat format) {
141 | return format.format(date);
142 | }
143 |
144 | /**
145 | * 将Date类型转为时间戳
146 | */
147 | public static long date2Milliseconds(Date date) {
148 | return date.getTime();
149 | }
150 |
151 | /**
152 | * 将时间戳转为Date类型
153 | */
154 | public static Date milliseconds2Date(long milliseconds) {
155 | return new Date(milliseconds);
156 | }
157 |
158 | /**
159 | * 毫秒时间戳单位转换(单位:unit)
160 | * time1和time2格式都为yyyy-MM-dd HH:mm:ss
190 | */
191 | public static long getIntervalTime(String time1, String time2, int unit) {
192 | return getIntervalTime(time1, time2, unit, DEFAULT_SDF);
193 | }
194 |
195 | /**
196 | * 获取两个时间差(单位:unit)
197 | * time1和time2格式都为format
205 | */
206 | public static long getIntervalTime(String time1, String time2, int unit, SimpleDateFormat format) {
207 | return milliseconds2Unit(string2Milliseconds(time1, format)
208 | - string2Milliseconds(time2, format), unit);
209 | }
210 |
211 | /**
212 | * 获取两个时间差(单位:unit)
213 | * time1和time2都为Date
221 | */
222 | public static long getIntervalTime(Date time1, Date time2, int unit) {
223 | return milliseconds2Unit(date2Milliseconds(time2) - date2Milliseconds(time1), unit);
224 | }
225 |
226 | /**
227 | * 获取当前时间
228 | * 单位(毫秒)
229 | */
230 | public static long getCurTimeMills() {
231 | return System.currentTimeMillis();
232 | }
233 |
234 | /**
235 | * 获取当前时间
236 | * 格式为yyyy-MM-dd HH:mm:ss
237 | */
238 | public static String getCurTimeString() {
239 | return milliseconds2String(getCurTimeMills());
240 | }
241 |
242 | /**
243 | * 获取当前时间
244 | * 格式为用户自定义
245 | */
246 | public static String getCurTimeString(SimpleDateFormat format) {
247 | return milliseconds2String(getCurTimeMills(), format);
248 | }
249 |
250 | /**
251 | * 获取当前时间
252 | * Date类型
253 | */
254 | public static Date getCurTimeDate() {
255 | return new Date();
256 | }
257 |
258 | /**
259 | * 获取与当前时间的差(单位:unit)
260 | * time1和time2格式都为yyyy-MM-dd HH:mm:ss
267 | */
268 | public static long getIntervalByNow(String time, int unit) {
269 | return getIntervalByNow(time, unit, DEFAULT_SDF);
270 | }
271 |
272 | /**
273 | * 获取与当前时间的差(单位:unit)
274 | * time1和time2格式都为format
281 | */
282 | public static long getIntervalByNow(String time, int unit, SimpleDateFormat format) {
283 | return getIntervalTime(getCurTimeString(), time, unit, format);
284 | }
285 |
286 | /**
287 | * 获取与当前时间的差(单位:unit)
288 | * time1和time2格式都为format
295 | */
296 | public static long getIntervalByNow(Date time, int unit) {
297 | return getIntervalTime(getCurTimeDate(), time, unit);
298 | }
299 |
300 | /**
301 | * 判断闰年
302 | */
303 | public static boolean isLeapYear(int year) {
304 | return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
305 | }
306 |
307 | }
308 |
309 |
--------------------------------------------------------------------------------
/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 | * author: Blankj on 2016/8/2 21:24
12 | * blog: http://blankj.com
13 | * e-mail: blankj@qq.com
14 | *********************************************/
15 | public class UnclassifiedUtils {
16 |
17 | private UnclassifiedUtils() {
18 | throw new UnsupportedOperationException("u can't fuck me...");
19 | }
20 |
21 | /**
22 | * 获取服务是否开启
23 | * @param className 完整包名的服务类名
24 | */
25 | public static boolean isRunningService(String className, Context context) {
26 | // 进程的管理者,活动的管理者
27 | ActivityManager activityManager = (ActivityManager)
28 | context.getSystemService(Context.ACTIVITY_SERVICE);
29 | // 获取正在运行的服务,最多获取1000个
30 | List
95 | *
100 | */
101 | public static int getPhoneType(Context context) {
102 | TelephonyManager tm = (TelephonyManager) context
103 | .getSystemService(Context.TELEPHONY_SERVICE);
104 | return tm != null ? tm.getPhoneType() : -1;
105 | }
106 | ```
107 |
108 | ### 获取当前的网络类型(WIFI,2G,3G,4G)
109 | ``` java
110 | /**
111 | * 获取当前的网络类型(WIFI,2G,3G,4G)
112 | *
116 | *
123 | */
124 | public static int getNetWorkType(Context context) {
125 | int netType = NETWORK_NO;
126 | NetworkInfo info = getActiveNetworkInfo(context);
127 | if (info != null && info.isAvailable()) {
128 |
129 | if (info.getType() == ConnectivityManager.TYPE_WIFI) {
130 | netType = NETWORK_WIFI;
131 | } else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
132 | switch (info.getSubtype()) {
133 |
134 | case NETWORK_TYPE_GSM:
135 | case TelephonyManager.NETWORK_TYPE_GPRS:
136 | case TelephonyManager.NETWORK_TYPE_CDMA:
137 | case TelephonyManager.NETWORK_TYPE_EDGE:
138 | case TelephonyManager.NETWORK_TYPE_1xRTT:
139 | case TelephonyManager.NETWORK_TYPE_IDEN:
140 | netType = NETWORK_2G;
141 | break;
142 |
143 | case NETWORK_TYPE_TD_SCDMA:
144 | case TelephonyManager.NETWORK_TYPE_EVDO_A:
145 | case TelephonyManager.NETWORK_TYPE_UMTS:
146 | case TelephonyManager.NETWORK_TYPE_EVDO_0:
147 | case TelephonyManager.NETWORK_TYPE_HSDPA:
148 | case TelephonyManager.NETWORK_TYPE_HSUPA:
149 | case TelephonyManager.NETWORK_TYPE_HSPA:
150 | case TelephonyManager.NETWORK_TYPE_EVDO_B:
151 | case TelephonyManager.NETWORK_TYPE_EHRPD:
152 | case TelephonyManager.NETWORK_TYPE_HSPAP:
153 | netType = NETWORK_3G;
154 | break;
155 |
156 | case NETWORK_TYPE_IWLAN:
157 | case TelephonyManager.NETWORK_TYPE_LTE:
158 | netType = NETWORK_4G;
159 | break;
160 | default:
161 |
162 | String subtypeName = info.getSubtypeName();
163 | if (subtypeName.equalsIgnoreCase("TD-SCDMA")
164 | || subtypeName.equalsIgnoreCase("WCDMA")
165 | || subtypeName.equalsIgnoreCase("CDMA2000")) {
166 | netType = NETWORK_3G;
167 | } else {
168 | netType = NETWORK_UNKNOWN;
169 | }
170 | break;
171 | }
172 | } else {
173 | netType = NETWORK_UNKNOWN;
174 | }
175 | }
176 | return netType;
177 | }
178 |
179 | /**
180 | * 获取当前的网络类型(WIFI,2G,3G,4G)
181 | * 依赖上面的方法
182 | *
183 | * @param context
184 | * @return 网络类型名称
185 | *
186 | *
193 | */
194 | public static String getNetWorkTypeName(Context context) {
195 | switch (getNetWorkType(context)) {
196 | case NETWORK_WIFI:
197 | return "NETWORK_WIFI";
198 | case NETWORK_4G:
199 | return "NETWORK_4G";
200 | case NETWORK_3G:
201 | return "NETWORK_3G";
202 | case NETWORK_2G:
203 | return "NETWORK_2G";
204 | case NETWORK_NO:
205 | return "NETWORK_NO";
206 | default:
207 | return "NETWORK_UNKNOWN";
208 | }
209 | }
210 | ```
211 |
--------------------------------------------------------------------------------
/about_phone.md:
--------------------------------------------------------------------------------
1 | # 手机相关
2 | ### 判断设备是否是手机
3 | ``` java
4 | /**
5 | * 判断设备是否是手机
6 | */
7 | public static boolean isPhone(Context context) {
8 | TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
9 | return tm.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
10 | }
11 | ```
12 |
13 | ### 获取手机的IMIE
14 | ``` java
15 | /**
16 | * 获取当前设备的IMIE
17 | *
39 | * DeviceId(IMEI) = 99000311726612
40 | * DeviceSoftwareVersion = 00
41 | * Line1Number =
42 | * NetworkCountryIso = cn
43 | * NetworkOperator = 46003
44 | * NetworkOperatorName = 中国电信
45 | * NetworkType = 6
46 | * honeType = 2
47 | * SimCountryIso = cn
48 | * SimOperator = 46003
49 | * SimOperatorName = 中国电信
50 | * SimSerialNumber = 89860315045710604022
51 | * SimState = 5
52 | * SubscriberId(IMSI) = 460030419724900
53 | * VoiceMailNumber = *86
54 | *
55 | */
56 | public static String getPhoneStatus(Context context) {
57 | TelephonyManager tm = (TelephonyManager) context
58 | .getSystemService(Context.TELEPHONY_SERVICE);
59 | String str = "";
60 | str += "DeviceId(IMEI) = " + tm.getDeviceId() + "\n";
61 | str += "DeviceSoftwareVersion = " + tm.getDeviceSoftwareVersion() + "\n";
62 | str += "Line1Number = " + tm.getLine1Number() + "\n";
63 | str += "NetworkCountryIso = " + tm.getNetworkCountryIso() + "\n";
64 | str += "NetworkOperator = " + tm.getNetworkOperator() + "\n";
65 | str += "NetworkOperatorName = " + tm.getNetworkOperatorName() + "\n";
66 | str += "NetworkType = " + tm.getNetworkType() + "\n";
67 | str += "honeType = " + tm.getPhoneType() + "\n";
68 | str += "SimCountryIso = " + tm.getSimCountryIso() + "\n";
69 | str += "SimOperator = " + tm.getSimOperator() + "\n";
70 | str += "SimOperatorName = " + tm.getSimOperatorName() + "\n";
71 | str += "SimSerialNumber = " + tm.getSimSerialNumber() + "\n";
72 | str += "SimState = " + tm.getSimState() + "\n";
73 | str += "SubscriberId(IMSI) = " + tm.getSubscriberId() + "\n";
74 | str += "VoiceMailNumber = " + tm.getVoiceMailNumber() + "\n";
75 | return str;
76 | }
77 | ```
78 |
79 | ### 跳至填充好phoneNumber的拨号界面
80 | ``` java
81 | /**
82 | * 跳至填充好phoneNumber的拨号界面
83 | */
84 | public static void dial(Context context, String phoneNumber) {
85 | context.startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)));
86 | }
87 | ```
88 |
89 | ### 拨打phoneNumber
90 | ``` java
91 | /**
92 | * 拨打phoneNumber
93 | *
84 | *
87 | */
88 | public static boolean isStatusBarExists(Activity activity) {
89 | WindowManager.LayoutParams params = activity.getWindow().getAttributes();
90 | return (params.flags & LayoutParams.FLAG_FULLSCREEN) != LayoutParams.FLAG_FULLSCREEN;
91 | }
92 | ```
93 |
94 | ### 获取ActionBar高度
95 | ``` java
96 | /**
97 | * 获取ActionBar高度
98 | */
99 | public static int getActionBarHeight(Activity activity) {
100 | TypedValue tv = new TypedValue();
101 | if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
102 | return TypedValue.complexToDimensionPixelSize(tv.data, activity.getResources().getDisplayMetrics());
103 | }
104 | return 0;
105 | }
106 | ```
107 |
108 | ### 设置屏幕为横屏
109 | ```
110 | /**
111 | * 设置屏幕为横屏
112 | *
108 | * UNIT_MSEC:毫秒
109 | * UNIT_SEC :秒
110 | * UNIT_MIN :分
111 | * UNIT_HOUR:小时
112 | * UNIT_DAY :天
113 | *
114 | */
115 | private static long milliseconds2Unit(long milliseconds, int unit) {
116 | switch (unit) {
117 | case UNIT_MSEC:
118 | case UNIT_SEC:
119 | case UNIT_MIN:
120 | case UNIT_HOUR:
121 | case UNIT_DAY:
122 | return Math.abs(milliseconds) / unit;
123 | }
124 | return -1;
125 | }
126 | ```
127 |
128 | ### 获取两个时间差(单位:unit)
129 | ``` java
130 | /**
131 | * 获取两个时间差(单位:unit)
132 | *
133 | * UNIT_MSEC:毫秒
134 | * UNIT_SEC :秒
135 | * UNIT_MIN :分
136 | * UNIT_HOUR:小时
137 | * UNIT_DAY :天
138 | *
139 | *
148 | * UNIT_MSEC:毫秒
149 | * UNIT_SEC :秒
150 | * UNIT_MIN :分
151 | * UNIT_HOUR:小时
152 | * UNIT_DAY :天
153 | *
154 | *
164 | * UNIT_MSEC:毫秒
165 | * UNIT_SEC :秒
166 | * UNIT_MIN :分
167 | * UNIT_HOUR:小时
168 | * UNIT_DAY :天
169 | *
170 | *
217 | * UNIT_MSEC:毫秒
218 | * UNIT_SEC :秒
219 | * UNIT_MIN :分
220 | * UNIT_HOUR:小时
221 | * UNIT_DAY :天
222 | *
231 | * UNIT_MSEC:毫秒
232 | * UNIT_SEC :秒
233 | * UNIT_MIN :分
234 | * UNIT_HOUR:小时
235 | * UNIT_DAY :天
236 | *
245 | * UNIT_MSEC:毫秒
246 | * UNIT_SEC :秒
247 | * UNIT_MIN :分
248 | * UNIT_HOUR:小时
249 | * UNIT_DAY :天
250 | *
67 | * PHONE_TYPE_NONE : 0 手机制式未知
68 | * PHONE_TYPE_GSM : 1 手机制式为GSM,移动和联通
69 | * PHONE_TYPE_CDMA : 2 手机制式为CDMA,电信
70 | * PHONE_TYPE_SIP : 3
71 | *
72 | */
73 | public static int getPhoneType(Context context) {
74 | TelephonyManager tm = (TelephonyManager) context
75 | .getSystemService(Context.TELEPHONY_SERVICE);
76 | return tm != null ? tm.getPhoneType() : -1;
77 | }
78 |
79 | /**
80 | * 获取手机连接的网络类型(2G,3G,4G)
81 | *
63 | * DeviceId(IMEI) = 99000311726612
64 | * DeviceSoftwareVersion = 00
65 | * Line1Number =
66 | * NetworkCountryIso = cn
67 | * NetworkOperator = 46003
68 | * NetworkOperatorName = 中国电信
69 | * NetworkType = 6
70 | * honeType = 2
71 | * SimCountryIso = cn
72 | * SimOperator = 46003
73 | * SimOperatorName = 中国电信
74 | * SimSerialNumber = 89860315045710604022
75 | * SimState = 5
76 | * SubscriberId(IMSI) = 460030419724900
77 | * VoiceMailNumber = *86
78 | *
79 | */
80 | public static String getPhoneStatus(Context context) {
81 | TelephonyManager tm = (TelephonyManager) context
82 | .getSystemService(Context.TELEPHONY_SERVICE);
83 | String str = "";
84 | str += "DeviceId(IMEI) = " + tm.getDeviceId() + "\n";
85 | str += "DeviceSoftwareVersion = " + tm.getDeviceSoftwareVersion() + "\n";
86 | str += "Line1Number = " + tm.getLine1Number() + "\n";
87 | str += "NetworkCountryIso = " + tm.getNetworkCountryIso() + "\n";
88 | str += "NetworkOperator = " + tm.getNetworkOperator() + "\n";
89 | str += "NetworkOperatorName = " + tm.getNetworkOperatorName() + "\n";
90 | str += "NetworkType = " + tm.getNetworkType() + "\n";
91 | str += "honeType = " + tm.getPhoneType() + "\n";
92 | str += "SimCountryIso = " + tm.getSimCountryIso() + "\n";
93 | str += "SimOperator = " + tm.getSimOperator() + "\n";
94 | str += "SimOperatorName = " + tm.getSimOperatorName() + "\n";
95 | str += "SimSerialNumber = " + tm.getSimSerialNumber() + "\n";
96 | str += "SimState = " + tm.getSimState() + "\n";
97 | str += "SubscriberId(IMSI) = " + tm.getSubscriberId() + "\n";
98 | str += "VoiceMailNumber = " + tm.getVoiceMailNumber() + "\n";
99 | return str;
100 | }
101 |
102 | /**
103 | * 跳至填充好phoneNumber的拨号界面
104 | */
105 | public static void dial(Context context, String phoneNumber) {
106 | context.startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)));
107 | }
108 |
109 | /**
110 | * 拨打phoneNumber
111 | *
95 | *
98 | */
99 | public static boolean isStatusBarExists(Activity activity) {
100 | LayoutParams params = activity.getWindow().getAttributes();
101 | return (params.flags & LayoutParams.FLAG_FULLSCREEN) != LayoutParams.FLAG_FULLSCREEN;
102 | }
103 |
104 | /**
105 | * 获取ActionBar高度
106 | */
107 | public static int getActionBarHeight(Activity activity) {
108 | TypedValue tv = new TypedValue();
109 | if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
110 | return TypedValue.complexToDimensionPixelSize(tv.data, activity.getResources().getDisplayMetrics());
111 | }
112 | return 0;
113 | }
114 |
115 | /**
116 | * 设置屏幕为横屏
117 | *
23 | * 日期和时间格式由日期和时间模式字符串指定。在日期和时间模式字符串中,未加引号的字母 'A' 到 'Z' 和 'a' 到 'z'
24 | * 被解释为模式字母,用来表示日期或时间字符串元素。文本可以使用单引号 (') 引起来,以免进行解释。"''"
25 | * 表示单引号。所有其他字符均不解释;只是在格式化时将它们简单复制到输出字符串,或者在分析时与输入字符串进行匹配。
26 | *
27 | * 定义了以下模式字母(所有其他字符 'A' 到 'Z' 和 'a' 到 'z' 都被保留):
28 | *
29 | *
50 | *
51 | *
52 | *
30 | * 字母 日期或时间元素 表示 示例
31 | * G Era 标志符 Text AD
32 | * y 年 Year 1996; 96
33 | * M 年中的月份 Month July; Jul; 07
34 | * w 年中的周数 Number 27
35 | * W 月份中的周数 Number 2
36 | * D 年中的天数 Number 189
37 | * d 月份中的天数 Number 10
38 | * F 月份中的星期 Number 2
39 | * E 星期中的天数 Text Tuesday; Tue
40 | * a Am/pm 标记 Text PM
41 | * H 一天中的小时数(0-23) Number 0
42 | * k 一天中的小时数(1-24) Number 24
43 | * K am/pm 中的小时数(0-11) Number 0
44 | * h am/pm 中的小时数(1-12) Number 12
45 | * m 小时中的分钟数 Number 30
46 | * s 分钟中的秒数 Number 55
47 | * S 毫秒数 Number 978
48 | * z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
49 | * Z 时区 RFC 822 time zone -0800
53 | * yyyy-MM-dd 1969-12-31
54 | * yyyy-MM-dd 1970-01-01
55 | * yyyy-MM-dd HH:mm 1969-12-31 16:00
56 | * yyyy-MM-dd HH:mm 1970-01-01 00:00
57 | * yyyy-MM-dd HH:mmZ 1969-12-31 16:00-0800
58 | * yyyy-MM-dd HH:mmZ 1970-01-01 00:00+0000
59 | * yyyy-MM-dd HH:mm:ss.SSSZ 1969-12-31 16:00:00.000-0800
60 | * yyyy-MM-dd HH:mm:ss.SSSZ 1970-01-01 00:00:00.000+0000
61 | * yyyy-MM-dd'T'HH:mm:ss.SSSZ 1969-12-31T16:00:00.000-0800
62 | * yyyy-MM-dd'T'HH:mm:ss.SSSZ 1970-01-01T00:00:00.000+0000
63 | *
64 | */
65 | public static final SimpleDateFormat DEFAULT_SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
66 | /**
67 | * 各时间单位与毫秒的倍数
68 | */
69 | public static final int UNIT_MSEC = 1;
70 | public static final int UNIT_SEC = 1000;
71 | public static final int UNIT_MIN = 60000;
72 | public static final int UNIT_HOUR = 3600000;
73 | public static final int UNIT_DAY = 86400000;
74 |
75 | /**
76 | * 将时间戳转为时间字符串
77 | *
161 | * UNIT_MSEC:毫秒
162 | * UNIT_SEC :秒
163 | * UNIT_MIN :分
164 | * UNIT_HOUR:小时
165 | * UNIT_DAY :天
166 | *
167 | */
168 | private static long milliseconds2Unit(long milliseconds, int unit) {
169 | switch (unit) {
170 | case UNIT_MSEC:
171 | case UNIT_SEC:
172 | case UNIT_MIN:
173 | case UNIT_HOUR:
174 | case UNIT_DAY:
175 | return Math.abs(milliseconds) / unit;
176 | }
177 | return -1;
178 | }
179 |
180 | /**
181 | * 获取两个时间差(单位:unit)
182 | *
183 | * UNIT_MSEC:毫秒
184 | * UNIT_SEC :秒
185 | * UNIT_MIN :分
186 | * UNIT_HOUR:小时
187 | * UNIT_DAY :天
188 | *
189 | *
198 | * UNIT_MSEC:毫秒
199 | * UNIT_SEC :秒
200 | * UNIT_MIN :分
201 | * UNIT_HOUR:小时
202 | * UNIT_DAY :天
203 | *
204 | *
214 | * UNIT_MSEC:毫秒
215 | * UNIT_SEC :秒
216 | * UNIT_MIN :分
217 | * UNIT_HOUR:小时
218 | * UNIT_DAY :天
219 | *
220 | *
261 | * UNIT_MSEC:毫秒
262 | * UNIT_SEC :秒
263 | * UNIT_MIN :分
264 | * UNIT_HOUR:小时
265 | * UNIT_DAY :天
266 | *
275 | * UNIT_MSEC:毫秒
276 | * UNIT_SEC :秒
277 | * UNIT_MIN :分
278 | * UNIT_HOUR:小时
279 | * UNIT_DAY :天
280 | *
289 | * UNIT_MSEC:毫秒
290 | * UNIT_SEC :秒
291 | * UNIT_MIN :分
292 | * UNIT_HOUR:小时
293 | * UNIT_DAY :天
294 | *