2011-01-04 14 views
37

Czy można uzyskać wolną pamięć na urządzeniu z Androidem (nie na karcie SD) za pomocą zestawu SDK systemu Android?Uzyskaj wolną przestrzeń w pamięci wewnętrznej

Jeśli tak, w jaki sposób?

+2

Możliwy duplikat [systemu Android ma bezpłatny rozmiar wewnętrznej/zewnętrznej pamięci] (https://stackoverflow.com/questions/8133417/android-get-free-size-of-internal-external-memory) –

Odpowiedz

63

this wpis może dobrze pasować do Twojego pytania.

również sprawdzić this thread. jest tak dużo informacji tutaj na SO.

google trochę i tu jest rozwiązanie (znajdujący się w android git)

File path = Environment.getDataDirectory(); 
StatFs stat = new StatFs(path.getPath()); 
long blockSize = stat.getBlockSize(); 
long availableBlocks = stat.getAvailableBlocks(); 
return Formatter.formatFileSize(this, availableBlocks * blockSize); 
+1

Wierzę, że zacisk faktycznie pyta o rzeczywiste miejsce przechowywania, a nie wykorzystanie pamięci (wywnioskowałem to z wzmianki o karcie SD). – kcoppock

+0

dzięki, tak mówię o pamięci. – clamp

+1

Dobra odpowiedź. Z tego co widzę, nie daje to żadnych ostrzeżeń, czyniąc go głównym wątkiem bezpiecznym. W połowie oczekiwałem ostrzeżenia w trybie ścisłym, ponieważ dotyczy ono systemu plików. – Mattias

9

wygląda jak klasa StatFs może być to, co trzeba użyć. Nie jestem pewien, która ścieżka byłaby uważana za źródło urządzenia, ale uważam, że wynik byłby taki sam niezależnie od katalogu, o ile jest on częścią pamięci wewnętrznej. Coś takiego może działać:

StatFs stats = new StatFs("/data"); 
int availableBlocks = stats.getAvailableBlocks(); 
int blockSizeInBytes = stats.getBlockSize(); 
int freeSpaceInBytes = availableBlocks * blockSizeInBytes; 

Jeśli nic więcej, klasa StatFs powinna dać ci dobry początek, gdzie szukać.

+1

Fajnie! Próbowałem pobrać to dla "/", które nie działało. Użycie "/ data" działa dla pamięci wewnętrznej. –

2

Na urządzeniach, na których rozmiar pamięci wewnętrznej jest bardzo duży, nie działa, ponieważ wartość int jest zbyt mała. Na przykład na Motorola Xum to nie działa. Trzeba użyć czegoś takiego:

int freeSpaceInKilobytes = availableBlocks * (blockSizeInBytes/1024);

+0

Lub użyj długiego typu, nie int. –

24
/************************************************************************************************* 
Returns size in bytes. 

If you need calculate external memory, change this: 
    StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 
to this: 
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());   
**************************************************************************************************/ 
    public long TotalMemory() 
    { 
     StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 
     long Total = ((long) statFs.getBlockCount() * (long) statFs.getBlockSize()); 
     return Total; 
    } 

    public long FreeMemory() 
    { 
     StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 
     long Free = (statFs.getAvailableBlocks() * (long) statFs.getBlockSize()); 
     return Free; 
    } 

    public long BusyMemory() 
    { 
     StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 
     long Total = ((long) statFs.getBlockCount() * (long) statFs.getBlockSize()); 
     long Free = (statFs.getAvailableBlocks() * (long) statFs.getBlockSize()); 
     long Busy = Total - Free; 
     return Busy; 
    } 

Konwersja bajtów do czytelnej formie (jak 1 Mb, 1 Gb)

public static String floatForm (double d) 
    { 
     return new DecimalFormat("#.##").format(d); 
    } 


    public static String bytesToHuman (long size) 
    { 
     long Kb = 1 * 1024; 
     long Mb = Kb * 1024; 
     long Gb = Mb * 1024; 
     long Tb = Gb * 1024; 
     long Pb = Tb * 1024; 
     long Eb = Pb * 1024; 

     if (size < Kb)     return floatForm(  size ) + " byte"; 
     if (size >= Kb && size < Mb) return floatForm((double)size/Kb) + " Kb"; 
     if (size >= Mb && size < Gb) return floatForm((double)size/Mb) + " Mb"; 
     if (size >= Gb && size < Tb) return floatForm((double)size/Gb) + " Gb"; 
     if (size >= Tb && size < Pb) return floatForm((double)size/Tb) + " Tb"; 
     if (size >= Pb && size < Eb) return floatForm((double)size/Pb) + " Pb"; 
     if (size >= Eb)     return floatForm((double)size/Eb) + " Eb"; 

     return "???"; 
    } 
+4

Musisz rzucić blockCount i blockSize na długo przed wykonaniem matematyki. W przeciwnym razie metody te mogłyby zwrócić wartość ujemną, ponieważ całkowita liczba bloków razy wielkość bloku przekroczy maksymalną wartość dla int. Tak, użyłem kodu i otrzymałem negatywy. – christophercotton

+0

@christophercotton Dzięki! Gotowe. – XXX

+7

Będziesz musiał (Long) statFs.getBlockCount() * (long) statFs.getBlockSize(), aby upewnić się, że są rzucane poprawnie. – christophercotton

2
/** 
* @return Number of bytes available on internal storage 
*/ 
public static long getInternalAvailableSpace() { 
    long availableSpace = -1L; 
    try {StatFs stat = new StatFs(Environment.getDataDirectory() 
      .getPath()); 
     stat.restat(Environment.getDataDirectory().getPath()); 
     availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return availableSpace; 
} 
5

Istnieją pewne metody, które zostały wycofane przez Google od 2013 roku i może zmienić te metody (API 18+ only):

  • getAvailableBlocks() do getAvailableBlocksLong()
  • getBlockCount() do getBlockCountLong()
  • getBlockSize() do getBlockSizeLong()
  • getFreeBlocks() do getFreeBlocksLong()
Powiązane problemy