Android는 내부 / 외부 메모리의 무료 크기를 얻습니다.
내 장치의 내부 / 외부 저장소에있는 사용 가능한 메모리의 크기를 프로그래밍 방식으로 얻고 싶습니다. 이 코드를 사용하고 있습니다.
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
Log.e("","Available MB : "+megAvailable);
File path = Environment.getDataDirectory();
StatFs stat2 = new StatFs(path.getPath());
long blockSize = stat2.getBlockSize();
long availableBlocks = stat2.getAvailableBlocks();
String format = Formatter.formatFileSize(this, availableBlocks * blockSize);
Log.e("","Format : "+format);
그리고 내가 얻는 결과는 다음과 같습니다.
11-15 10:27:18.844: E/(25822): Available MB : 7572
11-15 10:27:18.844: E/(25822): Format : 869MB
문제는 1,96GB
지금 SdCard의 여유 메모리를 얻고 싶다는 것 입니다. 무료 크기를 얻을 수 있도록이 코드를 어떻게 수정할 수 있습니까?
다음은 귀하의 목적에 맞는 코드입니다.
public static boolean externalMemoryAvailable() {
return android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
}
public static String getAvailableInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSizeLong();
long availableBlocks = stat.getAvailableBlocksLong();
return formatSize(availableBlocks * blockSize);
}
public static String getTotalInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSizeLong();
long totalBlocks = stat.getBlockCountLong();
return formatSize(totalBlocks * blockSize);
}
public static String getAvailableExternalMemorySize() {
if (externalMemoryAvailable()) {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSizeLong();
long availableBlocks = stat.getAvailableBlocksLong();
return formatSize(availableBlocks * blockSize);
} else {
return ERROR;
}
}
public static String getTotalExternalMemorySize() {
if (externalMemoryAvailable()) {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSizeLong();
long totalBlocks = stat.getBlockCountLong();
return formatSize(totalBlocks * blockSize);
} else {
return ERROR;
}
}
public static String formatSize(long size) {
String suffix = null;
if (size >= 1024) {
suffix = "KB";
size /= 1024;
if (size >= 1024) {
suffix = "MB";
size /= 1024;
}
}
StringBuilder resultBuffer = new StringBuilder(Long.toString(size));
int commaOffset = resultBuffer.length() - 3;
while (commaOffset > 0) {
resultBuffer.insert(commaOffset, ',');
commaOffset -= 3;
}
if (suffix != null) resultBuffer.append(suffix);
return resultBuffer.toString();
}
RAM 크기 얻기
ActivityManager actManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
MemoryInfo memInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
long totalMemory = memInfo.totalMem;
이것이 내가 한 방법입니다.
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable;
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
bytesAvailable = stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
}
else {
bytesAvailable = (long)stat.getBlockSize() * (long)stat.getAvailableBlocks();
}
long megAvailable = bytesAvailable / (1024 * 1024);
Log.e("","Available MB : "+megAvailable);
API 9부터 다음을 수행 할 수 있습니다.
long freeBytesInternal = new File(ctx.getFilesDir().getAbsoluteFile().toString()).getFreeSpace();
long freeBytesExternal = new File(getExternalFilesDir(null).toString()).getFreeSpace();
사용 가능한 모든 저장소 폴더 (SD 카드 포함)를 얻으려면 먼저 저장소 파일을 가져옵니다.
File internalStorageFile=getFilesDir();
File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);
그런 다음 각각의 사용 가능한 크기를 얻을 수 있습니다.
3 가지 방법이 있습니다.
API 8 이하 :
StatFs stat=new StatFs(file.getPath());
long availableSizeInBytes=stat.getBlockSize()*stat.getAvailableBlocks();
API 9 이상 :
long availableSizeInBytes=file.getFreeSpace();
API 18 이상 (이전 버전이 정상이면 필요하지 않음) :
long availableSizeInBytes=new StatFs(file.getPath()).getAvailableBytes();
지금 얻은 멋진 형식의 문자열을 얻으려면 다음을 사용할 수 있습니다.
String formattedResult=android.text.format.Formatter.formatShortFileSize(this,availableSizeInBytes);
또는 정확한 바이트 수를보고 싶은 경우에 사용할 수 있지만 멋지게 :
NumberFormat.getInstance().format(availableSizeInBytes);
내부 저장소는 첫 번째 외부 저장소가 에뮬레이트 된 저장소이므로 첫 번째 외부 저장소와 동일 할 수 있다고 생각합니다.
편집 : Android Q 이상에서 StorageVolume을 사용하면 다음과 같은 것을 사용하여 각각의 여유 공간을 얻을 수 있다고 생각합니다.
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
AsyncTask.execute {
for (storageVolume in storageVolumes) {
val uuid: UUID = storageVolume.uuid?.let { UUID.fromString(it) } ?: StorageManager.UUID_DEFAULT
val allocatableBytes = storageManager.getAllocatableBytes(uuid)
Log.d("AppLog", "allocatableBytes:${android.text.format.Formatter.formatShortFileSize(this,allocatableBytes)}")
}
}
이것이 정확한지 확실하지 않고 각각의 전체 크기를 얻을 수있는 방법을 찾을 수 없어서 여기에 썼고 여기 에 대해 물었 습니다 .
@ Android-Droid- Environment.getExternalStorageDirectory()
SD 카드가 아니어도되는 외부 저장소에 대한 잘못된 점이며 내부 메모리의 마운트 일 수도 있습니다. 보다:
이 간단한 스 니펫 시도
public static String readableFileSize() {
long availableSpace = -1L;
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
availableSpace = (long) stat.getBlockSizeLong() * (long) stat.getAvailableBlocksLong();
else
availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
if(availableSpace <= 0) return "0";
final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
int digitGroups = (int) (Math.log10(availableSpace)/Math.log10(1024));
return new DecimalFormat("#,##0.#").format(availableSpace/Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}
It is very easy to find out the storage available if you get internal as well as external storage path. Also phone's external storage path really very easy to find out using
Environment.getExternalStorageDirectory().getPath();
So I am just concentrating on how to find out the paths of external removable storage like removable sdcard, USB OTG(not tested USB OTG as I have no USB OTG).
Below method will give a list of all possible external removable storage paths.
/**
* This method returns the list of removable storage and sdcard paths.
* I have no USB OTG so can not test it. Is anybody can test it, please let me know
* if working or not. Assume 0th index will be removable sdcard path if size is
* greater than 0.
* @return the list of removable storage paths.
*/
public static HashSet<String> getExternalPaths()
{
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try
{
final Process process = new ProcessBuilder().command("mount").redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1)
{
s = s + new String(buffer);
}
is.close();
}
catch (final Exception e)
{
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines)
{
if (!line.toLowerCase(Locale.US).contains("asec"))
{
if (line.matches(reg))
{
String[] parts = line.split(" ");
for (String part : parts)
{
if (part.startsWith("/"))
{
if (!part.toLowerCase(Locale.US).contains("vold"))
{
out.add(part.replace("/media_rw","").replace("mnt", "storage"));
}
}
}
}
}
}
//Phone's external storage path (Not removal SDCard path)
String phoneExternalPath = Environment.getExternalStorageDirectory().getPath();
//Remove it if already exist to filter all the paths of external removable storage devices
//like removable sdcard, USB OTG etc..
//When I tested it in ICE Tab(4.4.2), Swipe Tab(4.0.1) with removable sdcard, this method includes
//phone's external storage path, but when i test it in Moto X Play (6.0) with removable sdcard,
//this method does not include phone's external storage path. So I am going to remvoe the phone's
//external storage path to make behavior consistent in all the phone. Ans we already know and it easy
// to find out the phone's external storage path.
out.remove(phoneExternalPath);
return out;
}
Quick addition to External memory topic
Don't be confused by the method name externalMemoryAvailable()
in Dinesh Prajapati's answer.
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
gives you the current state of the memory, if the media is present and mounted at its mount point with read/write access. You will get true
even on devices with no SD-cards, like Nexus 5. But still it's a 'must-have' method before any operations with storage.
To check if there is an SD-card on your device you can use method ContextCompat.getExternalFilesDirs()
It doesn't show transient devices, such as USB flash drives.
Also be aware that ContextCompat.getExternalFilesDirs()
on Android 4.3 and lower will always return only 1 entry (SD-card if it's available, otherwise Internal). You can read more about it here.
public static boolean isSdCardOnDevice(Context context) {
File[] storages = ContextCompat.getExternalFilesDirs(context, null);
if (storages.length > 1 && storages[0] != null && storages[1] != null)
return true;
else
return false;
}
in my case it was enough, but don't forget that some of the Android devices might have 2 SD-cards, so if you need all of them - adjust the code above.
@RequiresApi(api = Build.VERSION_CODES.O)
private void showStorageVolumes() {
StorageStatsManager storageStatsManager = (StorageStatsManager) getSystemService(Context.STORAGE_STATS_SERVICE);
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
if (storageManager == null || storageStatsManager == null) {
return;
}
List<StorageVolume> storageVolumes = storageManager.getStorageVolumes();
for (StorageVolume storageVolume : storageVolumes) {
final String uuidStr = storageVolume.getUuid();
final UUID uuid = uuidStr == null ? StorageManager.UUID_DEFAULT : UUID.fromString(uuidStr);
try {
Log.d("AppLog", "storage:" + uuid + " : " + storageVolume.getDescription(this) + " : " + storageVolume.getState());
Log.d("AppLog", "getFreeBytes:" + Formatter.formatShortFileSize(this, storageStatsManager.getFreeBytes(uuid)));
Log.d("AppLog", "getTotalBytes:" + Formatter.formatShortFileSize(this, storageStatsManager.getTotalBytes(uuid)));
} catch (Exception e) {
// IGNORED
}
}
}
StorageStatsManager class introduced Android O and above which can give you free and total byte in external/internal storage. For detailed with source code, you can read my following article. you can use reflection for lower than Android O
https://medium.com/cashify-engineering/how-to-get-storage-stats-in-android-o-api-26-4b92eca6805b
About external menory ,there is another way:
File external = Environment.getExternalStorageDirectory(); free:external.getFreeSpace(); total:external.getTotalSpace();
This is the way i did it..
internal Total memory
double totalSize = new File(getApplicationContext().getFilesDir().getAbsoluteFile().toString()).getTotalSpace();
double totMb = totalSize / (1024 * 1024);
Internal free size
double availableSize = new File(getApplicationContext().getFilesDir().getAbsoluteFile().toString()).getFreeSpace();
double freeMb = availableSize/ (1024 * 1024);
External free and total memory
long freeBytesExternal = new File(getExternalFilesDir(null).toString()).getFreeSpace();
int free = (int) (freeBytesExternal/ (1024 * 1024));
long totalSize = new File(getExternalFilesDir(null).toString()).getTotalSpace();
int total= (int) (totalSize/ (1024 * 1024));
String availableMb = free+"Mb out of "+total+"MB";
참고URL : https://stackoverflow.com/questions/8133417/android-get-free-size-of-internal-external-memory
'developer tip' 카테고리의 다른 글
iOS 6에서 UIViewController를 세로 방향으로 강제하는 방법 (0) | 2020.09.15 |
---|---|
기본적으로 루트로 방랑자 로그인 (0) | 2020.09.15 |
iPhone에 스플래시 화면이 나타날 때 상태 표시 줄을 숨기는 방법? (0) | 2020.09.15 |
Rails에서 rake db : seed를 실행할 때 US-ASCII (Argument Error)의 잘못된 바이트 시퀀스 (0) | 2020.09.15 |
스낵바의 배경색을 변경하는 방법은 무엇입니까? (0) | 2020.09.15 |