Truy cập Thư mục theo Phạm vi

Các ứng dụng như ứng dụng ảnh thường chỉ cần truy cập đến các thư mục đã quy định trong bộ nhớ ngoài như thư mục Pictures. Các phương pháp hiện tại để truy cập bộ nhớ lưu trữ ngoài vẫn chưa được thiết kế để dễ dàng cho phép truy cập thư mục đích cho những kiểu ứng dụng này. Ví dụ:

  • Việc yêu cầu READ_EXTERNAL_STORAGE hoặc WRITE_EXTERNAL_STORAGE trong bản kê khai của bạn sẽ cho phép truy cập đến tất cả các thư mục công khai trên bộ nhớ lưu trữ ngoài, mà có thể cấp nhiều quyền truy cập hơn những gì ứng dụng của bạn cần.
  • Sử dụng Khuôn khổ Truy cập Kho lưu trữ thường khiến người dùng chọn thư mục thông qua UI hệ thống. Đây là điều không cần thiết nếu ứng dụng của bạn luôn truy cập cùng một thư mục bên ngoài.

Android N cung cấp một API mới được đơn giản hóa để truy cập các thư mục lưu trữ bên ngoài thường dùng.

Truy cập một Thư mục lưu trữ bên ngoài

Sử dụng lớp StorageManager để lấy thực thể StorageVolume phù hợp. Sau đó tạo một ý định bằng cách gọi phương thức StorageVolume.createAccessIntent() của thực thể đó. Sử dụng ý định này để truy cập các thư mục lưu trữ bên ngoài. Để lấy danh sách tất cả các ổ đĩa, bao gồm các ổ đĩa media có thể tháo lắp, hãy sử dụng StorageManager.getVolumesList().

Đoạn mã sau là một ví dụ về cách mở thư mục Pictures trong bộ nhớ lưu trữ chính được chia sẻ:

StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
StorageVolume volume = sm.getPrimaryVolume();
Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code);

Hệ thống sẽ cố gắng cấp quyền truy cập tới thư mục bên ngoài và nếu cần sẽ xác nhận quyền truy cập với người dùng bằng một UI được đơn giản hóa:

Hình 1. Một ứng dụng yêu cầu truy cập tới thư mục Pictures.

Nếu người dùng cấp quyền truy cập, hệ thống sẽ gọi phương thức ghi đè onActivityResult() của bạn với mã kết quả là Activity.RESULT_OK và dữ liệu ý định có chứa URI. Hãy sử dụng URI được cung cấp để truy cập thông tin thư mục, giống như sử dụng các URI được trả về bởi Khuôn khổ Truy cập Kho lưu trữ.

Nếu người dùng không cấp quyền truy cập, hệ thống sẽ gọi phương thức ghi đè onActivityResult() của bạn với mã kết quả là Activity.RESULT_CANCELED và dữ liệu ý định có giá trị null.

Lưu ý: Lấy quyền truy cập tới một thư mục bên ngoài được chỉ định cũng sẽ cấp quyền truy cập tới các thư mục con thuộc thư mục đó.

Truy cập một Thư mục trên phương tiện tháo lắp được

Để sử dụng Truy cập Thư mục theo Phạm vi nhằm truy cập các thư mục trên phương tiện có thể tháo lắp, trước hết, hãy thêm một BroadcastReceiver để lắng nghe thông báo MEDIA_MOUNTED, ví dụ:

<receiver
    android:name=".MediaMountedReceiver"
    android:enabled="true"
    android:exported="true" >
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_MOUNTED" />
        <data android:scheme="file" />
    </intent-filter>
</receiver>

Khi người dùng kết nối một phương tiện có thể tháo lắp như thẻ SD thì hệ thống sẽ gửi một thông báo MEDIA_MOUNTED. Thông báo này sẽ cung cấp một đối tượng StorageVolume trong dữ liệu ý định mà bạn có thể sử dụng để truy cập các thư mục trên phương tiện có thể tháo lắp đó. Ví dụ sau sẽ truy cập thư mục Pictures trên phương tiện có thể tháo lắp:

// BroadcastReceiver has already cached the MEDIA_MOUNTED
// notification Intent in mediaMountedIntent
StorageVolume volume = (StorageVolume)
    mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code);

Thực hành Tốt nhất

Khi có thể, hãy duy trì URI truy cập thư mục bên ngoài để bạn không phải lặp lại yêu cầu người dùng cấp quyền truy cập. Khi người dùng đã cấp quyền truy cập, hãy gọi getContentResolver().takePersistableUriPermssion() với URI truy cập thư mục. Hệ thống sẽ duy trì URI và các yêu cầu truy cập sau này sẽ trả về RESULT_OK và không hiển thị UI xác nhận cho người dùng nữa.

Nếu người dùng từ chối quyền truy cập đến một thư mục bên ngoài thì đừng yêu cầu truy cập lại ngay lập tức. Lặp đi lặp lại yêu cầu truy cập sẽ dẫn đến trải nghiệm người dùng không tốt.