BẠN ĐÃ BIẾT VỀ SCOPED STORAGE – THAY ĐỔI MỚI NHẤT CỦA ANDROID?

27/05/2020 819
CODEWELL

Android là một trong những hệ điều hành phổ biến nhất hiện nay. Ở mỗi phiên bản cập nhật, Android đều nỗ lực cải thiện để đem lại sự hữu dụng, thuận tiện cho người dùng. Với Android 10 và Android 11 được ra mắt trong thời gian gần đây, một cải tiến mà các lập trình viên Android không thể bỏ qua là Scoped Storage.

 

Vậy Scoped Storage là gì?

 

 

Scoped Storage là một tính năng có tác dụng phân chia dung lượng lưu trữ thành các bộ sưu tập được chỉ định để giới hạn quyền truy cập vào bộ lưu trữ rộng. Hiểu một cách ngắn gọn, với Scoped Storage, mỗi ứng dụng sẽ được cung cấp thư mục riêng nhằm lưu trữ các tệp cần thiết dành cho dữ liệu người dùng và những ứng dụng khác không thể truy cập thư mục đó.

 

Developers cần quan tâm đến điều gì? 

 

 

  • Bắt đầu từ tháng 8/2020, các ứng dụng mới đưa lên Play Store sẽ phải hỗ trợ Android 10, tức trong Project phải cài đặt targetSdkVersion 29. Đối với các ứng dụng hiện có trên Play Store, từ sau 11/2020, khi muốn update lên cũng phải hỗ trợ Android 10. Do vậy,  các Project Android đang làm có liên quan đến việc thêm, xóa, sửa, chia sẻ file trên bộ nhớ chia sẻ (SDCard) đều phải tiến hành update để tránh lỗi.
  • Từ Android 10, API level 29, các truy cập trực tiếp vào bộ nhớ chia sẻ sẽ không thể tiếp tục, hàm getExternalStorageDirectory() sẽ không còn hoạt động. Việc này ảnh hưởng tới tất cả các ứng dụng trong việc thực hiện thao tác xử lý dữ liệu đọc, ghi, xóa file trên bộ nhớ chia sẻ.
  • Việc xử lý file trên bộ nhớ chia sẻ với các thư viện Native cũng bị lỗi tương tự.
  • Từ Android 10, bạn cũng không cần request permission đọc ghi bộ nhớ ngoài nữa và có thể điều chỉnh cấu hình manifest.xml như sau

<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”
android:maxSdkVersion=“28” />

 

Cách xử lý để thích ứng với những thay đổi

Xử lý tạm thời 

  • Lưu ý: Cách xử lý này chỉ nên dùng để chuyển dữ liệu (migrate data) của ứng dụng từ phiên bản cũ lên phiên bản mới dùng Scoped Storage.
  • Vẫn triển khai thiết lập targetSdkVersion 29
  • Khai báo thêm trong thẻ application của manifest.xml, bổ sung thuộc tính requestLegacyExternalStorage bằng true

<manifest … >

<application android:requestLegacyExternalStorage=”true” … >

</application>

</manifest>

  • Khi khai báo thuộc tính này true, AOS sẽ xử lý  theo cách truyền thống.
  • Tuy nhiên, cách xử lý này sẽ chỉ mang tính tạm thời và không có tác dụng với Android 11 và các phiên bản tiếp theo.

 

Xử lý tương thích Android 10 theo tiêu chuẩn

  • Bạn cần sử dụng bộ nhớ dành riêng cho mỗi ứng dụng (bộ nhớ trong và bộ nhớ ngoài). Các file lưu trong đó sẽ bị xóa bỏ khi gỡ cài đặt ứng dụng. Các file được tạo ra thường được mặc định là chỉ dùng cho ứng dụng, không nên dùng cho việc chia sẻ truy cập cho các ứng dụng khác. Tham khảo bài viết sau: https://developer.android.com/training/data-storage/app-specific
  • Xem ảnh tiếp theo để biết các thao tác cần có khi bạn muốn lưu trữ file lâu dài ngay cả khi gỡ ứng dụng hoặc muốn chia sẻ file cho các ứng dụng khác.

Các thao tác trên file: Xóa, chia sẻ, lưu trữ

 

  • Chia sẻ file:

Các ứng dụng cần thực hiện public file ra bộ nhớ chia sẻ. Các phương pháp cũ sử dụng MediaScannerConnection.scanFile() không còn hoạt động được nữa. Ví dụ dưới đây là thao tác lưu một file âm thanh ra bộ nhớ chia sẻ.

ContentResolver resolver = getApplicationContext()
.getContentResolver();

// Find all audio files on the primary external storage device.
Uri audioCollection = MediaStore.Audio.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL_PRIMARY);

ContentValues songDetails = new ContentValues();
newSongDetails.put(MediaStore.Audio.Media.DISPLAY_NAME,
“YourFile.mp3”);
newSongDetails.put(MediaStore.Audio.Media.IS_PENDING, 1);

Uri songContentUri = resolver
.insert(audioCollection, songDetails);

try (ParcelableFileDescriptor pfd =
resolver.openFileDescriptor(longSongContentUri, “w”, null)) {
// Thực hiện việc ghi dữ liệu vào file chia sẻ.
}

// Now that we’re finished, release the “pending” status, and allow other apps
// to play the audio track.
songDetails.clear();
songDetails.put(MediaStore.Audio.Media.IS_PENDING, 0);
resolver.update(longSongContentUri, songDetails, null, null);

  • Xóa, update file:

Việc xóa, update dữ liệu file không thuộc quyền quản lý của một ứng dụng hoặc không do ứng dụng tạo ra bây giờ sẽ cần xin quyền xác nhận từ User. Sau khi được User xác nhận cấp quyền, khi đó ứng dụng mới có thể thực hiện xóa file theo thao tác sau:

 

private static final int REQUEST_DELTE = 300;

…..

Private void deleteFile(long fileID){

try {

Uri uri = ContentUris.withAppendedId(

MediaStore.Images.Media.EXTERNAL_CONTENT_URI, fileID);

context.getContentResolver().delete(uri, null, null);

return true;

} catch (SecurityException secuex) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

if (secuex instanceof RecoverableSecurityException) {

try {

YourActivity.this.startIntentSenderForResult(((RecoverableSecurityException) secuex).getUserAction().getActionIntent().getIntentSender()

, REQUEST_DELTE, null, 0, 0, 0, null);

return false;

} catch (Exception e) {

}

 

}

}

return false;

}

}

 

………….

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_DELTE)                   {

deleteFile(fileID);

}

}

  • Đọc file:

Việc đọc file sẽ phải thông qua Content Uri. Việc truy cập file bằng đường dẫn trực tiếp ở bộ nhớ chia sẻ (SDCard) sẽ không thể thực hiện, trả về SecurityException. Để truy cập file thông qua Uri, bạn có thể sử dụng cách tạo Uri từ file ID như ví dụ dưới đây:

int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
Uri contentUri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id));

Kết  

Công nghệ là một lĩnh vực không ngừng thay đổi. Bởi vậy, chúng ta cần liên tục cập nhật thông tin và tìm cách thích ứng. Hy vọng bài viết này đã cung cấp những bài học hữu ích cho bạn về Scoped Storage – một trong những thay đổi mới nhất của Android.

 

Phó Việt Bách – CO-WELL Asia
Xem thêm các bài viết thú vị tại fanpage CO-WELL Asia