此问题发生的原因主要是在优化内存数字大小时,发生问题。根本原因为 进制 不同的问题。
这个方法会把实际内存大于标定内存(1000进制的)的内存卡显示翻倍。
例如:标定1T的内存卡 标定大小为 1 × 1000^4 (931G左右) ,如果 内存卡的实际大小 大于此大小的话,就会触发此bug。
frameworks/base/core/java/android/os/FileUtils.java
更改后:这样更改后会让显示的大小相比之前较为正常,例如:1T 大小的会显示为 1.1T,因为将内存大小转为字符的方法也是用1000进制算的,所以算出来会稍大一点。但是正常的显示一般为整数。所以有点瑕疵。
/**
* Round the given size of a storage device to a nice round power-of-two
* value, such as 256MB or 32GB. This avoids showing weird values like
* "29.5GB" in UI.
*
* @hide
*/
public static long roundStorageSize(long size) {
long val = 1;
long pow = 1;
long realPwo = 1;
while ((val * realPwo) < size) {
val <<= 1;
if (val > 512) {
val = 1;
pow *= 1000;
realPwo *= 1024;
}
}
if (size > val * pow) {
return val * realPwo;
}
return val * pow;
}
另一种改法 就是直接将优化算法,和内存转换字符的算法都 换成1024进制的。但是这样,你的手机显示内存和实际内存相差会变大。 比如一个空的内存卡插进去就会显示10%已被使用。
直接将 pow 改为1024. 然后再去改变 转为字符的方法。
public static long roundStorageSize(long size) {
long val = 1;
long pow = 1;
while ((val * pow) < size) {
val <<= 1;
if (val > 512) {
val = 1;
pow *= 1024;
}
}
return val * pow;
}
packages/apps/Settings/src/com/android/settings/deviceinfo/storage/StorageUtils.java
将Formatter.FLAG_SHORTER 改为 FLAG_IEC_UNITS
因为Formatter.FLAG_SHORTER 就会导致用1000进制去算。 (未验证)
/** Gets a summary which has a byte size information. */
public static String getStorageSummary(Context context, int resId, long bytes) {
final Formatter.BytesResult result = Formatter.formatBytes(context.getResources(),
bytes, Formatter.FLAG_SHORTER);
return context.getString(resId, result.value, result.units);
}
frameworks/base/core/java/android/text/format/Formatter.java
/** {@hide} */
@UnsupportedAppUsage
public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) {
final int unit = ((flags & FLAG_IEC_UNITS) != 0) ? 1024 : 1000;
final boolean isNegative = (sizeBytes < 0);
float result = isNegative ? -sizeBytes : sizeBytes;
int suffix = com.android.internal.R.string.byteShort;
long mult = 1;
if (result > 900) {
suffix = com.android.internal.R.string.kilobyteShort;
mult = unit;
result = result / unit;
}
if (result > 900) {
suffix = com.android.internal.R.string.megabyteShort;
mult *= unit;
result = result / unit;
}
if (result > 900) {
suffix = com.android.internal.R.string.gigabyteShort;
mult *= unit;
result = result / unit;
}
if (result > 900) {
suffix = com.android.internal.R.string.terabyteShort;
mult *= unit;
result = result / unit;
}
if (result > 900) {
suffix = com.android.internal.R.string.petabyteShort;
mult *= unit;
result = result / unit;
}
// Note we calculate the rounded long by ourselves, but still let String.format()
// compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to
// floating point errors.
final int roundFactor;
final String roundFormat;
if (mult == 1 || result >= 100) {
roundFactor = 1;
roundFormat = "%.0f";
} else if (result < 1) {
roundFactor = 100;
roundFormat = "%.2f";
} else if (result < 10) {
if ((flags & FLAG_SHORTER) != 0) {
roundFactor = 10;
roundFormat = "%.1f";
} else {
roundFactor = 100;
roundFormat = "%.2f";
}
} else { // 10 <= result < 100
if ((flags & FLAG_SHORTER) != 0) {
roundFactor = 1;
roundFormat = "%.0f";
} else {
roundFactor = 100;
roundFormat = "%.2f";
}
}
if (isNegative) {
result = -result;
}
final String roundedString = String.format(roundFormat, result);
// Note this might overflow if abs(result) >= Long.MAX_VALUE / 100, but that's like 80PB so
// it's okay (for now)...
final long roundedBytes =
(flags & FLAG_CALCULATE_ROUNDED) == 0 ? 0
: (((long) Math.round(result * roundFactor)) * mult / roundFactor);
final String units = res.getString(suffix);
return new BytesResult(roundedString, units, roundedBytes);
}
这里改了之后会导致外部存储的计算也按1024进制算,会导致显示比之前要小;因为外部存储和内部存储的 容量大小读取方法不一样,不会调用到roundStorageSize(),所以还要调整一下外部存储的 容量读取方法,也按1024进制去计算。
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
index be2a64a..1d161be 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
@@ -18,6 +18,7 @@
import android.app.usage.StorageStatsManager;
import android.content.Context;
+import android.os.FileUtils;
import android.os.UserHandle;
import android.util.Log;
@@ -101,6 +102,7 @@
throw new IOException();
}
mTotalBytes = rootFile.getTotalSpace();
+ mTotalBytes = FileUtils.roundStorageSize(mTotalBytes);
mUsedBytes = mTotalBytes - rootFile.getFreeSpace();
}
} catch (IOException e) {