diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2d1261dc..25524c6004 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +* `20/04/13` [add] NumberUtils. Publish v1.28.0. +* `20/04/12` [opt] TimeUtils#SDF_THREAD_LOCAL. +* `20/04/11` [add] SDCardUtils#getXxTotalSize, SDCardUtils#getXxAvailableSize. FileUtils#getFsTotalSize, FileUtils#getFsAvailableSize. * `20/04/10` [fix] FileUtils#isFileExists; FragmentUtils#getTop bug. Publish v1.27.6. * `20/04/09` [add] UriUtils#res2Uri, UriUtils#uri2File support QQBrowser; ThreadUtils#getMainHandler; PathUtils#getxxPathExternalFirst. * `20/04/08` [fix] ActivityUtils#finish bug. Publish v1.27.5. diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy index 6d63dbc373..fbaeaa926e 100644 --- a/buildSrc/src/main/groovy/Config.groovy +++ b/buildSrc/src/main/groovy/Config.groovy @@ -15,7 +15,7 @@ class Config { static minSdkVersion = 14 static targetSdkVersion = 29 static versionCode = 1_026_001 - static versionName = '1.27.6'// E.g. 1.9.72 => 1,009,072 + static versionName = '1.28.0'// E.g. 1.9.72 => 1,009,072 // lib version static gradlePluginVersion = '3.5.0' diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/device/DeviceActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/device/DeviceActivity.kt index ea68079605..1df423ded3 100644 --- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/device/DeviceActivity.kt +++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/device/DeviceActivity.kt @@ -4,8 +4,6 @@ import android.content.Context import android.content.Intent import android.os.Build import com.blankj.common.activity.CommonActivity -import com.blankj.common.activity.CommonActivityItemsView -import com.blankj.common.activity.CommonActivityTitleView import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt index ad09fff804..0c51475952 100644 --- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt +++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt @@ -32,19 +32,15 @@ class SDCardActivity : CommonActivity() { } override fun bindItems(): MutableList> { - val mountedSDCardPath = SDCardUtils.getMountedSDCardPath() - val sizeItems = CollectionUtils.collect(mountedSDCardPath) { input -> - val totalInfo = "total: " + ConvertUtils.byte2FitMemorySize(SDCardUtils.getTotalSize(input)) - val availableInfo = "available: " + ConvertUtils.byte2FitMemorySize(SDCardUtils.getAvailableSize(input)) - CommonItemTitle(input, "$totalInfo, $availableInfo") - } - val result: ArrayList> = CollectionUtils.newArrayList( + return CollectionUtils.newArrayList( CommonItemTitle("isSDCardEnableByEnvironment", SDCardUtils.isSDCardEnableByEnvironment().toString()), CommonItemTitle("getSDCardPathByEnvironment", SDCardUtils.getSDCardPathByEnvironment()), CommonItemTitle("getSDCardInfo", SDCardUtils.getSDCardInfo().toString()), - CommonItemTitle("getMountedSDCardPath", mountedSDCardPath.toString()) + CommonItemTitle("getMountedSDCardPath", SDCardUtils.getMountedSDCardPath().toString()), + CommonItemTitle("getExternalTotalSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getExternalTotalSize(), 2)), + CommonItemTitle("getExternalAvailableSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getExternalAvailableSize(), 2)), + CommonItemTitle("getInternalTotalSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getInternalTotalSize(), 2)), + CommonItemTitle("getInternalAvailableSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getInternalAvailableSize(), 2)) ) - result.addAll(sizeItems) - return result } } diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md index aa98d9ac5e..43dad16553 100644 --- a/lib/utilcode/README-CN.md +++ b/lib/utilcode/README-CN.md @@ -2,10 +2,10 @@ Gradle: ```groovy -implementation 'com.blankj:utilcode:1.27.6' +implementation 'com.blankj:utilcode:1.28.0' // if u use AndroidX, use the following -implementation 'com.blankj:utilcodex:1.27.6' +implementation 'com.blankj:utilcodex:1.28.0' ``` @@ -487,6 +487,8 @@ getFileName : 根据全路径获取文件名 getFileNameNoExtension : 根据全路径获取文件名不带拓展名 getFileExtension : 根据全路径获取文件拓展名 notifySystemToScan : 通知系统扫描文件 +getFsTotalSize : 获取文件系统总大小 +getFsAvailableSize : 获取文件系统可用大小 ``` * ### Fragment 相关 -> [FragmentUtils.java][fragment.java] -> [Demo][fragment.demo] @@ -695,6 +697,12 @@ cancelAll : 取消所有通知 setNotificationBarVisibility: 设置通知栏是否可见 ``` +* ### 数字相关 -> [NumberUtils.java][number.java] -> [Test][number.test] +``` +format : 格式化 +float2Double: 浮点转双精度 +``` + * ### 对象相关 -> [ObjectUtils.java][object.java] -> [Test][object.test] ``` isEmpty : 判断对象是否为空 @@ -913,8 +921,10 @@ isSDCardEnableByEnvironment: 根据 Environment 判断 SD 卡是否可用 getSDCardPathByEnvironment : 根据 Environment 获取 SD 卡路径 getSDCardInfo : 获取 SD 卡信息 getMountedSDCardPath : 获取已挂载的 SD 卡路径 -getTotalSize : 获取 SD 卡总大小 -getAvailableSize : 获取 SD 卡可用大小 +getExternalTotalSize : 获取外置 SD 卡总大小 +getExternalAvailableSize : 获取外置 SD 卡可用大小 +getInternalTotalSize : 获取内置 SD 卡总大小 +getInternalAvailableSize : 获取内置 SD 卡可用大小 ``` * ### 服务相关 -> [ServiceUtils.java][service.java] @@ -1086,6 +1096,7 @@ setDeliver : 设置任务结束后交付的线程 * ### 时间相关 -> [TimeUtils.java][time.java] -> [Test][time.test] ``` +getSafeDateFormat : 获取安全的日期格式 millis2String : 将时间戳转为时间字符串 string2Millis : 将时间字符串转为时间戳 string2Date : 将时间字符串转为 Date 类型 @@ -1306,6 +1317,9 @@ getComments : 获取压缩文件中的注释链表 [notification.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/NotificationUtils.java [notification.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/notification/NotificationActivity.kt +[number.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/NumberUtils.java +[number.test]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/NumberUtilsTest.java + [object.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/ObjectUtils.java [object.test]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java diff --git a/lib/utilcode/README.md b/lib/utilcode/README.md index ed5ee22da0..6a3adf119e 100644 --- a/lib/utilcode/README.md +++ b/lib/utilcode/README.md @@ -2,10 +2,10 @@ Gradle: ```groovy -implementation 'com.blankj:utilcode:1.27.6' +implementation 'com.blankj:utilcode:1.28.0' // if u use AndroidX, use the following -implementation 'com.blankj:utilcodex:1.27.6' +implementation 'com.blankj:utilcodex:1.28.0' ``` @@ -487,6 +487,8 @@ getFileName getFileNameNoExtension getFileExtension notifySystemToScan +getFsTotalSize +getFsAvailableSize ``` * ### About Fragment -> [FragmentUtils.java][fragment.java] -> [Demo][fragment.demo] @@ -695,6 +697,12 @@ cancelAll setNotificationBarVisibility ``` +* ### About Number -> [NumberUtils.java][number.java] -> [Test][number.test] +``` +format +float2Double +``` + * ### About Object -> [ObjectUtils.java][object.java] -> [Test][object.test] ``` isEmpty @@ -913,8 +921,10 @@ isSDCardEnableByEnvironment getSDCardPathByEnvironment getSDCardInfo getMountedSDCardPath -getTotalSize -getAvailableSize +getExternalTotalSize +getExternalAvailableSize +getInternalTotalSize +getInternalAvailableSize ``` * ### About Service -> [ServiceUtils.java][service.java] @@ -1086,6 +1096,7 @@ setDeliver * ### About Time -> [TimeUtils.java][time.java] -> [Test][time.test] ``` +getSafeDateFormat millis2String string2Millis string2Date @@ -1303,6 +1314,9 @@ getComments [notification.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/NotificationUtils.java [notification.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/notification/NotificationActivity.kt +[number.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/NumberUtils.java +[number.test]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/NumberUtilsTest.java + [object.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/ObjectUtils.java [object.test]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java index 1ff359395c..630321ce69 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java @@ -418,16 +418,32 @@ public static double byte2MemorySize(final long byteSize, */ @SuppressLint("DefaultLocale") public static String byte2FitMemorySize(final long byteSize) { + return byte2FitMemorySize(byteSize, 3); + } + + /** + * Size of byte to fit size of memory. + *

to three decimal places

+ * + * @param byteSize Size of byte. + * @param precision The precision + * @return fit size of memory + */ + @SuppressLint("DefaultLocale") + public static String byte2FitMemorySize(final long byteSize, int precision) { + if (precision < 0) { + throw new IllegalArgumentException("precision shouldn't be less than zero!"); + } if (byteSize < 0) { - return "shouldn't be less than zero!"; + throw new IllegalArgumentException("byteSize shouldn't be less than zero!"); } else if (byteSize < MemoryConstants.KB) { - return String.format("%.3fB", (double) byteSize); + return String.format("%." + precision + "fB", (double) byteSize); } else if (byteSize < MemoryConstants.MB) { - return String.format("%.3fKB", (double) byteSize / MemoryConstants.KB); + return String.format("%." + precision + "fKB", (double) byteSize / MemoryConstants.KB); } else if (byteSize < MemoryConstants.GB) { - return String.format("%.3fMB", (double) byteSize / MemoryConstants.MB); + return String.format("%." + precision + "fMB", (double) byteSize / MemoryConstants.MB); } else { - return String.format("%.3fGB", (double) byteSize / MemoryConstants.GB); + return String.format("%." + precision + "fGB", (double) byteSize / MemoryConstants.GB); } } diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java index d182f9b9f2..217af05fa8 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java @@ -5,6 +5,8 @@ import android.content.res.AssetFileDescriptor; import android.net.Uri; import android.os.Build; +import android.os.StatFs; +import android.text.TextUtils; import java.io.BufferedInputStream; import java.io.File; @@ -76,10 +78,10 @@ public static boolean isFileExists(final String filePath) { if (file.exists()) { return true; } - return isFileExists29(filePath); + return isFileExistsApi29(filePath); } - private static boolean isFileExists29(String filePath) { + private static boolean isFileExistsApi29(String filePath) { if (Build.VERSION.SDK_INT >= 29) { try { Uri uri = Uri.parse(filePath); @@ -1379,6 +1381,15 @@ public static String getFileExtension(final String filePath) { return filePath.substring(lastPoi + 1); } + /** + * Notify system to scan the file. + * + * @param filePath The path of file. + */ + public static void notifySystemToScan(final String filePath) { + notifySystemToScan(getFileByPath(filePath)); + } + /** * Notify system to scan the file. * @@ -1393,12 +1404,45 @@ public static void notifySystemToScan(final File file) { } /** - * Notify system to scan the file. + * Return the total size of file system. * - * @param filePath The path of file. + * @param anyPathInFs Any path in file system. + * @return the total size of file system */ - public static void notifySystemToScan(final String filePath) { - notifySystemToScan(getFileByPath(filePath)); + public static long getFsTotalSize(String anyPathInFs) { + if (TextUtils.isEmpty(anyPathInFs)) return 0; + StatFs statFs = new StatFs(anyPathInFs); + long blockSize; + long totalSize; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { + blockSize = statFs.getBlockSizeLong(); + totalSize = statFs.getBlockCountLong(); + } else { + blockSize = statFs.getBlockSize(); + totalSize = statFs.getBlockCount(); + } + return blockSize * totalSize; + } + + /** + * Return the available size of file system. + * + * @param anyPathInFs Any path in file system. + * @return the available size of file system + */ + public static long getFsAvailableSize(final String anyPathInFs) { + if (TextUtils.isEmpty(anyPathInFs)) return 0; + StatFs statFs = new StatFs(anyPathInFs); + long blockSize; + long availableSize; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { + blockSize = statFs.getBlockSizeLong(); + availableSize = statFs.getAvailableBlocksLong(); + } else { + blockSize = statFs.getBlockSize(); + availableSize = statFs.getAvailableBlocks(); + } + return blockSize * availableSize; } /////////////////////////////////////////////////////////////////////////// diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java index 892a428e92..7ab11b7981 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java @@ -243,7 +243,7 @@ public static void fixAndroidBug5497(@NonNull final Activity activity) { /** * Fix the bug of 5497 in Android. - *

Don't set adjustResize

+ *

It will clean the adjustResize

* * @param window The window. */ diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/NumberUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/NumberUtils.java new file mode 100644 index 0000000000..5828927cd2 --- /dev/null +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/NumberUtils.java @@ -0,0 +1,198 @@ +package com.blankj.utilcode.util; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.NumberFormat; + +/** + *
+ *     author: blankj
+ *     blog  : http://blankj.com
+ *     time  : 2020/04/12
+ *     desc  : utils about number
+ * 
+ */ +public final class NumberUtils { + + private static final ThreadLocal DF_THREAD_LOCAL = new ThreadLocal() { + @Override + protected DecimalFormat initialValue() { + return (DecimalFormat) NumberFormat.getInstance(); + } + }; + + public static DecimalFormat getSafeDecimalFormat() { + return DF_THREAD_LOCAL.get(); + } + + private NumberUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + /** + * Format the value. + * + * @param value The value. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @return the format value + */ + public static String format(float value, int fractionDigits) { + return format(value, false, 1, fractionDigits, true); + } + + /** + * Format the value. + * + * @param value The value. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @param isHalfUp True to rounded towards the nearest neighbor. + * @return the format value + */ + public static String format(float value, int fractionDigits, boolean isHalfUp) { + return format(value, false, 1, fractionDigits, isHalfUp); + } + + /** + * Format the value. + * + * @param value The value. + * @param minIntegerDigits The minimum number of digits allowed in the integer portion of value. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @param isHalfUp True to rounded towards the nearest neighbor. + * @return the format value + */ + public static String format(float value, int minIntegerDigits, int fractionDigits, boolean isHalfUp) { + return format(value, false, minIntegerDigits, fractionDigits, isHalfUp); + } + + /** + * Format the value. + * + * @param value The value. + * @param isGrouping True to set grouping will be used in this format, false otherwise. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @return the format value + */ + public static String format(float value, boolean isGrouping, int fractionDigits) { + return format(value, isGrouping, 1, fractionDigits, true); + } + + /** + * Format the value. + * + * @param value The value. + * @param isGrouping True to set grouping will be used in this format, false otherwise. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @param isHalfUp True to rounded towards the nearest neighbor. + * @return the format value + */ + public static String format(float value, boolean isGrouping, int fractionDigits, boolean isHalfUp) { + return format(value, isGrouping, 1, fractionDigits, isHalfUp); + } + + /** + * Format the value. + * + * @param value The value. + * @param isGrouping True to set grouping will be used in this format, false otherwise. + * @param minIntegerDigits The minimum number of digits allowed in the integer portion of value. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @param isHalfUp True to rounded towards the nearest neighbor. + * @return the format value + */ + public static String format(float value, boolean isGrouping, int minIntegerDigits, int fractionDigits, boolean isHalfUp) { + return format(float2Double(value), isGrouping, minIntegerDigits, fractionDigits, isHalfUp); + } + + /** + * Format the value. + * + * @param value The value. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @return the format value + */ + public static String format(double value, int fractionDigits) { + return format(value, false, 1, fractionDigits, true); + } + + /** + * Format the value. + * + * @param value The value. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @param isHalfUp True to rounded towards the nearest neighbor. + * @return the format value + */ + public static String format(double value, int fractionDigits, boolean isHalfUp) { + return format(value, false, 1, fractionDigits, isHalfUp); + } + + /** + * Format the value. + * + * @param value The value. + * @param minIntegerDigits The minimum number of digits allowed in the integer portion of value. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @param isHalfUp True to rounded towards the nearest neighbor. + * @return the format value + */ + public static String format(double value, int minIntegerDigits, int fractionDigits, boolean isHalfUp) { + return format(value, false, minIntegerDigits, fractionDigits, isHalfUp); + } + + /** + * Format the value. + * + * @param value The value. + * @param isGrouping True to set grouping will be used in this format, false otherwise. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @return the format value + */ + public static String format(double value, boolean isGrouping, int fractionDigits) { + return format(value, isGrouping, 1, fractionDigits, true); + } + + /** + * Format the value. + * + * @param value The value. + * @param isGrouping True to set grouping will be used in this format, false otherwise. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @param isHalfUp True to rounded towards the nearest neighbor. + * @return the format value + */ + public static String format(double value, boolean isGrouping, int fractionDigits, boolean isHalfUp) { + return format(value, isGrouping, 1, fractionDigits, isHalfUp); + } + + /** + * Format the value. + * + * @param value The value. + * @param isGrouping True to set grouping will be used in this format, false otherwise. + * @param minIntegerDigits The minimum number of digits allowed in the integer portion of value. + * @param fractionDigits The number of digits allowed in the fraction portion of value. + * @param isHalfUp True to rounded towards the nearest neighbor. + * @return the format value + */ + public static String format(double value, boolean isGrouping, int minIntegerDigits, int fractionDigits, boolean isHalfUp) { + DecimalFormat nf = getSafeDecimalFormat(); + nf.setGroupingUsed(isGrouping); + nf.setRoundingMode(isHalfUp ? RoundingMode.HALF_UP : RoundingMode.DOWN); + nf.setMinimumIntegerDigits(minIntegerDigits); + nf.setMinimumFractionDigits(fractionDigits); + nf.setMaximumFractionDigits(fractionDigits); + return nf.format(value); + } + + /** + * Float to double. + * + * @param value The value. + * @return the number of double + */ + public static double float2Double(float value) { + return new BigDecimal(String.valueOf(value)).doubleValue(); + } +} diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/SDCardUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/SDCardUtils.java index 2db6c16ed0..10952e779d 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/SDCardUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/SDCardUtils.java @@ -2,9 +2,9 @@ import android.content.Context; import android.os.Environment; -import android.os.StatFs; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; +import android.text.format.Formatter; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; @@ -125,44 +125,41 @@ public static List getMountedSDCardPath() { return path; } + /** - * Return the total size of sdcard. + * Return the total size of external storage * - * @param path The path. - * @return the total size of sdcard + * @return the total size of external storage */ - public static long getTotalSize(String path) { - StatFs statFs = new StatFs(path); - long blockSize; - long totalSize; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { - blockSize = statFs.getBlockSizeLong(); - totalSize = statFs.getBlockCountLong(); - } else { - blockSize = statFs.getBlockSize(); - totalSize = statFs.getBlockCount(); - } - return blockSize * totalSize; + public static long getExternalTotalSize() { + return UtilsBridge.getFsTotalSize(getSDCardPathByEnvironment()); } /** - * Return the available size of sdcard. + * Return the available size of external storage. * - * @param path The path. - * @return the available size of sdcard + * @return the available size of external storage */ - public static long getAvailableSize(final String path) { - StatFs statFs = new StatFs(path); - long blockSize; - long availableSize; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { - blockSize = statFs.getBlockSizeLong(); - availableSize = statFs.getAvailableBlocksLong(); - } else { - blockSize = statFs.getBlockSize(); - availableSize = statFs.getAvailableBlocks(); - } - return blockSize * availableSize; + public static long getExternalAvailableSize() { + return UtilsBridge.getFsAvailableSize(getSDCardPathByEnvironment()); + } + + /** + * Return the total size of internal storage + * + * @return the total size of internal storage + */ + public static long getInternalTotalSize() { + return UtilsBridge.getFsTotalSize(Environment.getDataDirectory().getAbsolutePath()); + } + + /** + * Return the available size of internal storage. + * + * @return the available size of internal storage + */ + public static long getInternalAvailableSize() { + return UtilsBridge.getFsAvailableSize(Environment.getDataDirectory().getAbsolutePath()); } public static class SDCardInfo { @@ -170,11 +167,15 @@ public static class SDCardInfo { private String path; private String state; private boolean isRemovable; + private long totalSize; + private long availableSize; SDCardInfo(String path, String state, boolean isRemovable) { this.path = path; this.state = state; this.isRemovable = isRemovable; + this.totalSize = UtilsBridge.getFsTotalSize(path); + this.availableSize = UtilsBridge.getFsAvailableSize(path); } public String getPath() { @@ -189,12 +190,22 @@ public boolean isRemovable() { return isRemovable; } + public long getTotalSize() { + return totalSize; + } + + public long getAvailableSize() { + return availableSize; + } + @Override public String toString() { return "SDCardInfo {" + "path = " + path + ", state = " + state + ", isRemovable = " + isRemovable + + ", totalSize = " + Formatter.formatFileSize(Utils.getApp(), totalSize) + + ", availableSize = " + Formatter.formatFileSize(Utils.getApp(), availableSize) + '}'; } } diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java index dde92562c2..d328524c36 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java @@ -1,5 +1,6 @@ package com.blankj.utilcode.util; +import android.annotation.SuppressLint; import android.support.annotation.NonNull; import com.blankj.utilcode.constant.TimeConstants; @@ -10,7 +11,9 @@ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; /** *
@@ -22,19 +25,26 @@
  */
 public final class TimeUtils {
 
-    private static final ThreadLocal SDF_THREAD_LOCAL = new ThreadLocal<>();
+    private static final ThreadLocal> SDF_THREAD_LOCAL
+            = new ThreadLocal>() {
+        @Override
+        protected Map initialValue() {
+            return new HashMap<>();
+        }
+    };
 
     private static SimpleDateFormat getDefaultFormat() {
-        return getDateFormat("yyyy-MM-dd HH:mm:ss");
+        return getSafeDateFormat("yyyy-MM-dd HH:mm:ss");
     }
 
-    private static SimpleDateFormat getDateFormat(String pattern) {
-        SimpleDateFormat simpleDateFormat = SDF_THREAD_LOCAL.get();
+    @SuppressLint("SimpleDateFormat")
+    public static SimpleDateFormat getSafeDateFormat(String pattern) {
+        Map sdfMap = SDF_THREAD_LOCAL.get();
+        //noinspection ConstantConditions
+        SimpleDateFormat simpleDateFormat = sdfMap.get(pattern);
         if (simpleDateFormat == null) {
-            simpleDateFormat = new SimpleDateFormat(pattern, Locale.getDefault());
-            SDF_THREAD_LOCAL.set(simpleDateFormat);
-        } else {
-            simpleDateFormat.applyPattern(pattern);
+            simpleDateFormat = new SimpleDateFormat(pattern);
+            sdfMap.put(pattern, simpleDateFormat);
         }
         return simpleDateFormat;
     }
@@ -62,7 +72,7 @@ public static String millis2String(final long millis) {
      * @return the formatted time string
      */
     public static String millis2String(long millis, @NonNull final String pattern) {
-        return millis2String(millis, getDateFormat(pattern));
+        return millis2String(millis, getSafeDateFormat(pattern));
     }
 
     /**
@@ -95,7 +105,7 @@ public static long string2Millis(final String time) {
      * @return the milliseconds
      */
     public static long string2Millis(final String time, @NonNull final String pattern) {
-        return string2Millis(time, getDateFormat(pattern));
+        return string2Millis(time, getSafeDateFormat(pattern));
     }
 
     /**
@@ -133,7 +143,7 @@ public static Date string2Date(final String time) {
      * @return the date
      */
     public static Date string2Date(final String time, @NonNull final String pattern) {
-        return string2Date(time, getDateFormat(pattern));
+        return string2Date(time, getSafeDateFormat(pattern));
     }
 
     /**
@@ -171,7 +181,7 @@ public static String date2String(final Date date) {
      * @return the formatted time string
      */
     public static String date2String(final Date date, @NonNull final String pattern) {
-        return getDateFormat(pattern).format(date);
+        return getSafeDateFormat(pattern).format(date);
     }
 
     /**
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/UtilsBridge.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/UtilsBridge.java
index 5ce1d4f7b2..41e052a5e9 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/UtilsBridge.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/UtilsBridge.java
@@ -276,6 +276,14 @@ static boolean createFileByDeleteOldFile(final File file) {
         return FileUtils.createFileByDeleteOldFile(file);
     }
 
+    static long getFsTotalSize(String path) {
+        return FileUtils.getFsTotalSize(path);
+    }
+
+    static long getFsAvailableSize(String path) {
+        return FileUtils.getFsAvailableSize(path);
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // GsonUtils
     ///////////////////////////////////////////////////////////////////////////
@@ -402,6 +410,10 @@ static String getCurrentProcessName() {
     ///////////////////////////////////////////////////////////////////////////
     // SDCardUtils
     ///////////////////////////////////////////////////////////////////////////
+    static String getSDCardPathByEnvironment() {
+        return SDCardUtils.getSDCardPathByEnvironment();
+    }
+
     static boolean isSDCardEnableByEnvironment() {
         return SDCardUtils.isSDCardEnableByEnvironment();
     }
diff --git a/lib/utilcode/src/test/java/com/blankj/utilcode/util/BaseTest.java b/lib/utilcode/src/test/java/com/blankj/utilcode/util/BaseTest.java
index 6e097938bf..36a5fa9f3c 100644
--- a/lib/utilcode/src/test/java/com/blankj/utilcode/util/BaseTest.java
+++ b/lib/utilcode/src/test/java/com/blankj/utilcode/util/BaseTest.java
@@ -1,7 +1,7 @@
 package com.blankj.utilcode.util;
 
 import android.support.annotation.NonNull;
-import java.util.concurrent.Executor;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -9,6 +9,8 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowLog;
 
+import java.util.concurrent.Executor;
+
 /**
  * 
  *     author: Blankj
@@ -18,7 +20,7 @@
  * 
*/ @RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE,shadows = { ShadowLog.class }) +@Config(manifest = Config.NONE, shadows = {ShadowLog.class}) public class BaseTest { @BusUtils.Bus(tag = "base") diff --git a/lib/utilcode/src/test/java/com/blankj/utilcode/util/NumberUtilsTest.java b/lib/utilcode/src/test/java/com/blankj/utilcode/util/NumberUtilsTest.java new file mode 100644 index 0000000000..a2fa94f0c6 --- /dev/null +++ b/lib/utilcode/src/test/java/com/blankj/utilcode/util/NumberUtilsTest.java @@ -0,0 +1,45 @@ +package com.blankj.utilcode.util; + +import org.junit.Assert; +import org.junit.Test; + +/** + *
+ *     author: blankj
+ *     blog  : http://blankj.com
+ *     time  : 2020/04/13
+ *     desc  : test NumberUtils
+ * 
+ */ +public class NumberUtilsTest { + + @Test + public void format() { + double val = Math.PI * 100000;// 314159.2653589793 + + Assert.assertEquals("314159.27", NumberUtils.format(val, 2)); + Assert.assertEquals("314159.265", NumberUtils.format(val, 3)); + + Assert.assertEquals("314159.27", NumberUtils.format(val, 2, true)); + Assert.assertEquals("314159.26", NumberUtils.format(val, 2, false)); + + Assert.assertEquals("00314159.27", NumberUtils.format(val, 8, 2, true)); + Assert.assertEquals("0000314159.27", NumberUtils.format(val, 10, 2, true)); + + Assert.assertEquals("314,159.27", NumberUtils.format(val, true, 2)); + Assert.assertEquals("314159.27", NumberUtils.format(val, false, 2)); + + Assert.assertEquals("314159.27", NumberUtils.format(val, false, 2, true)); + Assert.assertEquals("314159.26", NumberUtils.format(val, false, 2, false)); + + Assert.assertEquals("314159.27", NumberUtils.format(val, false, 2, true)); + Assert.assertEquals("314159.265", NumberUtils.format(val, false, 3, false)); + } + + @Test + public void float2Double() { + float val = 3.14f; + System.out.println((double) val); + System.out.println(NumberUtils.float2Double(val)); + } +} \ No newline at end of file