Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách lấy dung lượng bộ nhớ trống (Internal/External) trên Android bằng Kotlin

Giới thiệu

Hướng dẫn này trình bày cách lấy dung lượng bộ nhớ trống (available space) của bộ nhớ nội bộ (internal) hoặc ngoại bộ (external/SD card) trên Android sử dụng StatFs và Kotlin.

Các bước thực hiện

Bước 1: Tạo dự án mới

Tạo project: File → New Project.

Bước 2: Thiết kế giao diện (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        android:text="Tutorials Point"
        android:textAlignment="center"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="32sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textAlignment="center"
        android:textColor="@android:color/background_dark"
        android:textSize="24sp"
        android:textStyle="bold" />

</RelativeLayout>

Bước 3: Xử lý logic (src/MainActivity.kt)

import android.os.Bundle
import android.os.Environment
import android.os.StatFs
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var textView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "KotlinApp"

        textView = findViewById(R.id.textView)

        // Lấy đường dẫn bộ nhớ ngoài (External Storage)
        val path = Environment.getExternalStorageDirectory().absolutePath
        val stat = StatFs(path)

        // Tính dung lượng trống (API 18+)
        val bytesAvailable: Long = stat.blockSizeLong * stat.availableBlocksLong
        val megAvailable = bytesAvailable / (1024 * 1024)

        textView.text = "Available External Free Space: $megAvailable MB"
    }
}

Bước 4: Cấu hình Manifest (androidManifest.xml)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.q1">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Ứng dụng sẽ hiển thị dung lượng trống của bộ nhớ ngoài (external storage) tính bằng MB.

Giải thích các tham số StatFs

  • blockSizeLong: Kích thước một block (bytes)
  • availableBlocksLong: Số block có sẵn cho ứng dụng (non-root)
  • blockCountLong: Tổng số block
  • freeBlocksLong: Số block trống tuyệt đối (cần root)

Mở rộng: Lấy cả Internal và External

fun getStorageInfo(): String {
    val builder = StringBuilder()

    // External Storage (Primary shared storage)
    val extPath = Environment.getExternalStorageDirectory().absolutePath
    val extStat = StatFs(extPath)
    val extFree = extStat.blockSizeLong * extStat.availableBlocksLong
    builder.append("External: ").append(formatBytes(extFree)).append("\n")

    // Internal Storage (App-specific)
    val intPath = filesDir.absolutePath
    val intStat = StatFs(intPath)
    val intFree = intStat.blockSizeLong * intStat.availableBlocksLong
    builder.append("Internal (App): ").append(formatBytes(intFree))

    return builder.toString()
}

fun formatBytes(bytes: Long): String {
    return when {
        bytes >= 1024L * 1024 * 1024 -> String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024))
        bytes >= 1024L * 1024 -> String.format("%.2f MB", bytes / (1024.0 * 1024))
        bytes >= 1024L -> String.format("%.2f KB", bytes / 1024.0)
        else -> "$bytes B"
    }
}

Lưu ý quan trọng

  • Android 10+ (API 29+): Truy cập bộ nhớ ngoài bị hạn chế (Scoped Storage). getExternalStorageDirectory() đã deprecated.
  • Dùng Context.getExternalFilesDirs() hoặc StorageManager cho API mới.
  • Không cần quyền READ_EXTERNAL_STORAGE để đọc dung lượng trống.
  • Kết quả có thể khác với cài đặt Settings do hệ thống dự trữ dung lượng.