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ố blockfreeBlocksLong: 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ặcStorageManagercho 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.