Android 8.1.0 原生系统,Settings 中,点击 “存储” 查看内存使用时,发现内存使用情况都是使用 GB 做的单位,但是如果某一类型文件实在是太小了,比如照片和视频中只有100KB 左右大小,如果还是使用 GB 作为计算格式的话,那最终显示出来的就只是0GB 了,这样不方便用户对自己内存空间有详细的了解,如下:

所以,我们优化一下当前界面的内存大小的显示规则:
如果某一个目录下文件大小大于1GB,那么我们以 GB 为单位;
如果某一个目录下文件大小小于1GB但大于1MB,那么我们以 MB 为单位;
如果某一个目录下文件大小小于1MB但大于1KB,那么我们以 KB 为单位;
如果某一个目录下文件大小于1KB,那么我们以 KB 为单位;
接下来我们开始修改,主要是修改下面这个类:
E:/folder/vendor/rockchip/hxxxx/apps/Settings/src/com/android/settings/deviceinfo/StorageItemPreference.java
首先查看这个类中 setStorageSize(long size, long total) 方法调用了 setSummary() 关键方法:
public void setStorageSize(long size, long total) {
//关键方法
setSummary(
FileSizeFormatter.formatFileSize(
getContext(),
size,
MeasureUnit.GIGABYTE,
FileSizeFormatter.GIGABYTE_IN_BYTES));
if (total == 0) {
mProgressPercent = 0;
} else {
mProgressPercent = (int)(size * PROGRESS_MAX / total);
}
updateProgressBar();
}
在这个方法中,我们看到无论传递进来的数据大小是多少,在这里都会以GB 的格式去显示,所以,我们要做的就是修改并替换setSummary()这个方法:先对传入的数据做一下大小判断,并按照我们上面绿色文字需求去修改:
使用 preCalculatedBeforeSetStorageSize(long size) 方法 替换 setSummary()方法:
/**
* Pre calculated before set storage size:
* If the file size is not 1G, the file size is displayed in MB;
* if the file is not 1MB, the file size is displayed in KB.
* Note:As of O, the prefixes are used in their standard meanings in the SI system,
* so kB = 1000 bytes, MB = 1,000,000 bytes, etc.
*In Android N and earlier, powers of 1024 are used instead, with KB = 1024 bytes,
* MB = 1,048,576 bytes, etc.
*
* @param size
*/
private void preCalculatedBeforeSetStorageSize(long size){
final int GB_MODE = 2;
final int MB_MODE = 1;
final int KB_MODE = 0;
int currentCalculatedMode = 2;
MeasureUnit currentMeasureUnit = null;
long currentFileSizeFormatter = 0;
//Initialize the format parameters.
currentCalculatedMode = getCurrentCalculatedMode(size);
switch (currentCalculatedMode){
case KB_MODE:
currentMeasureUnit = MeasureUnit.KILOBYTE;
currentFileSizeFormatter = FileSizeFormatter.KILOBYTE_IN_BYTES;
break;
case MB_MODE:
currentMeasureUnit = MeasureUnit.MEGABYTE;
currentFileSizeFormatter = FileSizeFormatter.MEGABYTE_IN_BYTES;
break;
case GB_MODE:
currentMeasureUnit = MeasureUnit.GIGABYTE;
currentFileSizeFormatter = FileSizeFormatter.GIGABYTE_IN_BYTES;
break;
}
//Set parameters.
setSummary(FileSizeFormatter.formatFileSize(
getContext(),
size,
currentMeasureUnit,
currentFileSizeFormatter));
}
/**
* Get current calculated Mode.
* @param size
* @return int CalculatedMode.
*/
private int getCurrentCalculatedMode(long size){
final int GB_MODE = 2;
final int MB_MODE = 1;
final int KB_MODE = 0;
int currentMode = 2;
//Get current calculated Mode.
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
//Android O and later
if (div(size,1000000000,4) >= 1.2){
//GB
currentMode = GB_MODE;
}else if (div(size,1000000,4) >= 1.2){
//MB
currentMode = MB_MODE;
}else if (div(size,1000,4) >= 1.2){
//KB
currentMode = KB_MODE;
}
}else {
//Android N and earlier
if (div(size,1073741824,4) >= 1.2){
//GB
currentMode = GB_MODE;
}else if (div(size,1048576,4) >= 1.2){
//MB
currentMode = MB_MODE;
}else if (div(size,1024,4) >= 1.2){
//KB
currentMode = KB_MODE;
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
//Default setting is GB.
currentMode = GB_MODE;
return currentMode;
}
return currentMode;
}
/**
* Precise division method.
*
* @param value1 Divisor
* @param value2 divisor
* @param scale Rounding Mode
* @return quotient
* @throws IllegalAccessException
*/
public static double div(double value1, double value2, int scale) throws IllegalAccessException {
if (scale < 0) {
throw new IllegalAccessException("Accuracy cannot be less than 0.");
}
BigDecimal vauleb1 = new BigDecimal(Double.toString(value1));
BigDecimal vauleb2 = new BigDecimal(Double.toString(value2));
return vauleb1.divide(vauleb2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
导包:
import android.os.Build;
import java.math.BigDecimal;
修改完成之后:

以上是全部内容。