Android Scoped Storage

by phongpn3
119 views

Chào mọi người,

Hôm nọ mình có có làm task liên quan đến việc maintain một project được phát triển từ năm 2019 với API support là 29 (Android 9). Một loạt các functions phải cập nhật lại trong đó có functions liên quan đến storage. Chắc hẳn nhiều bạn cũng đoán được vấn đề này liên quan đến Scoped Storage – một tính năng mới ra mắt từ Android 10. Mình muốn chia sẻ một chút kiến thức của mình liên quan đến nó và các giải pháp xử lý khi gặp phải bài toán như của mình.

Sau đây, là một số ý chính mình sẽ đề cập

  1. Vấn đề
  2. Scoped Storage là gì?
  3. Các tính năng chính của Scoped Storage
  4. Cách xử lý với những thay đổi

Nào mình bắt đầu

  1. Vấn đề

    Trước Android 10, chúng ta có khái niệm về Shared Storage. Mỗi ứng dụng trong thiết bị đều có một số bộ nhớ riêng trong bộ nhớ trong và bạn có thể tìm thấy ứng dụng này trong thư mục android / data / your_package_name. Ngoài bộ nhớ trong này, phần còn lại của bộ nhớ được gọi là Shared Storage. Một phần bộ nhớ mà mọi ứng dụng có quyền lưu trữ đều có thể truy cập, bao gồm Media Collections và các tập tin khác của các ứng dụng khác nhau. Từ việc này phát sinh ra một số vấn đề:

    1. Thứ nhất, ứng dụng nào đó chỉ cần thực hiện một số thao tác nhỏ trên một phần bộ nhớ (ví dụ như chỉ lấy ảnh từ phần bộ nhớ này và tải lên và không làm gì khác). Câu hỏi ở đây là tại sao phải cũng cấp cho ứng dụng đó toàn bộ quyền truy cập vào bộ lưu trữ chung đó?

    2. Vấn đề thứ hai là khi ứng dụng có khả năng ghi rộng như vậy trên bộ lưu trữ thì các tệp do ứng dụng tạo ra bị phân tán và khi người dùng gỡ cài đặt ứng dụng thì các tệp do ứng dụng tạo ra chỉ còn trong bộ lưu trữ và không bị xóa và mất rất nhiều không gian.

  2. 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 đó.

  3. Các tính năng chính của Scoped Storage

    1. Unrestricted access: Mọi ứng dụng đều có quyền truy cập không hạn chế vào bộ lưu trữ của riêng nó, tức là lưu trữ nội bộ cũng như bên ngoài. Vì vậy, với Android 10, bạn không cần cung cấp quyền lưu trữ để ghi tệp vào thư mục ứng dụng của riêng bạn trên thẻ SD.

    2. Unrestricted media: Bạn có quyền truy cập không hạn chế để đóng góp các tệp vào bộ sưu tập phương tiện và tải xuống ứng dụng của riêng bạn. Vì vậy, không cần phải xin phép nếu bạn muốn lưu bất kỳ hình ảnh, video hoặc bất kỳ tệp phương tiện nào khác trong bộ sưu tập phương tiện. Bạn có thể đọc hoặc ghi các tệp phương tiện do bạn tạo nhưng để đọc tệp phương tiện của ứng dụng khác, bạn cần phải có quyền READ_EXTERNAL_STORAGE từ người dùng. Ngoài ra, quyền WRITE_EXTERNAL_STORAGE sẽ không được chấp nhận trong bản phát hành Android tiếp theo và bạn sẽ có quyền truy cập đọc nếu bạn sử dụng WRITE_EXTERNAL_STORAGE. Bạn phải yêu cầu người dùng chỉnh sửa rõ ràng các tệp phương tiện không được đóng góp bởi ứng dụng của bạn.

    3. Media location metadata: Có quyền mới được giới thiệu trong Android 10, tức là ACCESS_MEDIA_LOCATION. Nếu bạn muốn có được vị trí của phương tiện truyền thông thì bạn phải có sự cho phép này

  4. Cách xử lý với những thay đổi

    1. 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

      image

    Lưu ý: Nếu bạn đang sử dụng Scoped Storage, thì bạn nên di chuyển tất cả các tệp media hoặc tất cả các tệp có trong Shared Storage vào thư mục của ứng dụng. Nếu không, bạn sẽ mất quyền truy cập vào các tập tin đó.

    1. Xử lý tương thích cho Android 10 và version cao hơ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. Bạn có thể tham khảo ở link hướng dẫn

      https://developer.android.com/training/data-storage/app-specific

      Các thao tác trên file: Save, Delete, Share

      1. Delete and 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:

        image

      2. Read 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:

        image

      3. Share 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ẻ.

        image

        image

        image

Kết luận: Mong là chia sẻ của mình đâu đấy sẽ giúp được một số bạn hiểu rõ hơn và có thể giải quyết một số vấn đề có thể các bạn sẽ gặp phải trong quá trình làm việc. Hẹn gặp lại các bạn trong các bài viết tiếp theo.

Source Code https://github.com/android/storage-samples/tree/main/MediaStore

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.