Cách làm của Google khá rối rắm nhưng kể ra thì cũng tiện.
Khái quát bộ nhớ Android
Internal là gì?
Internal chỉ có 1 loại duy nhất là nó lưu vào trong tên miền của app, những app khác không đọc được. Nó sẽ bị xoá hết khi người dùng xoá app. Ví dụ: /data/user/0/jp.co.abc/files/test.txt
Loại này phù hợp để lưu các thông tin yêu cầu bảo mật cao.
External là gì?
External có 2 loại chính và phụ (private & public external)
- Bộ nhớ ngoài chính là lưu vào trong thư mục root của hệ thống, những app khác đọc được thoải mái.
Nó sẽ không bị xoá khi người dùng xoá app. Ví dụ Gọi hàm Environment.getExternalStorageDirectory() sẽ ra path sau: /storage/emulated/0
Nếu đặt file nhạc hay ảnh trong đường dẫn này thì các app duyệt thư mục nó nhìn thấy hết.
Chú ý:
Từ Android 11 trở đi Google không cho phép lưu dữ liệu thoải mái tại thư mục root này nữa mà cần phải xin thêm quyền mới.
- Bộ nhớ ngoài phụ là lưu vào trong tên miền của app, những app khác đọc được. Nó sẽ bị xoá khi người dùng xoá app. Gọi hàm getExternalFilesDir() sẽ ra path sau: /storage/emulated/0/Android/data/jp.co.abc/files Cái private external này chỉ khác cái internal ở chỗ là app khác đọc được dữ liệu còn về cấu trúc thư mục y hệt internal.
public static String DIRECTORY_ALARMS = "Alarms";
public static String DIRECTORY_AUDIOBOOKS = "Audiobooks";
public static String DIRECTORY_DCIM = "DCIM";
public static String DIRECTORY_DOCUMENTS = "Documents";
public static String DIRECTORY_DOWNLOADS = "Download";
public static String DIRECTORY_MOVIES = "Movies";
public static String DIRECTORY_MUSIC = "Music";
public static String DIRECTORY_NOTIFICATIONS = "Notifications";
public static String DIRECTORY_PICTURES = "Pictures";
public static String DIRECTORY_PODCASTS = "Podcasts";
public static String DIRECTORY_RINGTONES = "Ringtones";
public static String DIRECTORY_SCREENSHOTS = "Screenshots";
Bộ nhớ ngoài này họ Android đã tạo sẵn cho chúng ta các loại thư mục này, vì vậy chúng ta có thể dùng luôn mà không cần tạo mới.
Ví dụ:
public static String FOLDER_PRODUC = getDefaultContext().getExternalFilesDir(Environment.DIRECTORY_MUSIC).getAbsolutePath() + File.separator;
Tóm lại
Internal và External là 2 từ khoá ám chỉ trong và ngoài app chứ không phải trong và ngoài bộ nhớ của điện thoại (lấy hệ quy chiếu là App không phải điện thoại).
Tương tự cách suy nghĩ khi bạn dùng FileOutputStream & FileInputStream:
- FileOutputStream: được dùng khi muốn ghi mảng byte “ra” file
- FileInputStream: được dùng khi muốn đọc mảng byte “từ” file
Thực hành và kiểm tra
Tạo sub thư mục trong bộ nhớ internal
Khi gọi thư mục files/ trong bộ nhớ trong của app dùng hàm: getFilesDir()
Ví dụ thêm thư mục con vào thư mục files: /data/data/jp.co.abc/files/subDir/
Bằng đoạn mã sau:
File subDir = new File(getDefaultContext().getFilesDir(), "subDir");
if(!subDir.exists() ){
subDir.mkdir();
}
Lưu ý: Nếu ta tạo thư mục bằng getDir() thì Android SDK nó tự tạo prefix là app_
File mydir = getDefaultContext().getDir("test_folder", Context.MODE_PRIVATE);
if (!mydir.exists())
{
boolean daTao = mydir.mkdirs();
}
Nhưng mình nghĩ dùng trong phạm vi thư mục files/ là đủ rồi. Do vậy từ giờ các cách tạo bên dưới mình sẽ làm việc trong thư mục files/
Tạo 1 file trong bộ nhớ internal cách 1
File subDir = new File(getDefaultContext().getFilesDir(), "subDir");
if (!subDir.exists()) {
subDir.mkdir();
}
try {
File fileTxt = new File(subDir, "test.json");
FileWriter writer = new FileWriter(fileTxt);
writer.append("test content");
writer.flush();
writer.close();
} catch (Exception e) {
LogI(e.getMessage());
}
Đoạn code trên tạo file trong thư mục con subDir, nếu muốn tạo ngay thư mục files thì chỉ cần gọi getDefaultContext().getFilesDir() hoặc làm theo cách 2 bên dưới.
Tạo 1 file trong bộ nhớ internal cách 2 (ngay trong thư mục files)
String fileName = "tesst.txt";
String content = "log content";
FileOutputStream outputStream;
try {
outputStream = getDefaultContext().openFileOutput(fileName, Context.MODE_PRIVATE);
outputStream.write(content.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Hàm test nhanh:
public static void testPath() {
LogI("bo nho trong app getFilesDir(): " + getDefaultContext().getFilesDir());
LogI("bo nho ngoai app - private getExternalFilesDir: " + getDefaultContext().getExternalFilesDir(null).getAbsolutePath());
LogI("bo nho ngoai app - public Environment.getExternalStorageDirectory(): " + Environment.getExternalStorageDirectory());
}
Tham khảo thêm: https://stackoverflow.com/questions/10123812/diff-between-getexternalfilesdir-and-getexternalstoragedirectory
NHÌN TỔNG THỂ HƠN VỀ BỘ NHỚ EXTERNAL CỦA ĐIỆN THOẠI & APP
Hình dưới đây bao gồm cả bộ nhớ ngoài của điện thoại nữa nên bạn có thể tham khảo.
TẢI FILE EXCEL TẠI ĐÂY
Các bài viết không xem thì tiếc:
- Đọc file và ghi file vào bộ nhớ internal Android từ thư mục raw
- Làm việc với font trong Android
- LƯU Ý KHI ĐƯA APP LÊN APP STORE & TESTFLIGHT TỪ ĐÔ TRỊNH | dotrinh.com
- Lập trình phóng to thu nhỏ ảnh pinch in – pinch out trong Android
- Chuyển một đối tượng sang Json trong Android
- Cách dùng Eventbus để truyền dữ liệu trong Android
- Lập trình với Recyclerview trong Android – Bài 2 | dotrinh.com
- Thêm nhiều domain trong Apache – Web Server
- Cách dùng AsyncTask trong Android
- Ý nghĩa của Certificates, App IDs, Provisioning Profiles khi cài đặt môi trường dev iOS
- Show Indicator trong Android | Hiển thị indicator trong Android
- Lập trình với Recyclerview trong Android – Bài 1 | dotrinh.com
- Phóng to thu nhỏ trong Android với ScaleGestureDetector
- Tổng quan nhất về ứng dụng Android
- Siêu tổng hợp android code snippets (cập nhật thường xuyên)
1 Comment