1page.title=Truy cập Thư mục theo Phạm vi 2page.keywords=preview,sdk,scoped directory access 3page.tags=androidn 4 5@jd:body 6 7<div id="qv-wrapper"> 8<div id="qv"> 9 <h2>Trong tài liệu này</h2> 10 <ol> 11 <li><a href="#accessing">Truy cập một Thư mục lưu trữ bên ngoài</a></li> 12 <li><a href="#removable">Truy cập một Thư mục trên Phương tiện tháo lắp được</a></li> 13 <li><a href="#best">Thực hành Tốt nhất</a></li> 14 </ol> 15</div> 16</div> 17 18<p>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 19bộ nhớ ngoài như thư mục <code>Pictures</code>. Các phương pháp 20 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 21truy cập thư mục đích cho những kiểu ứng dụng này. Ví dụ:</p> 22 23<ul> 24<li>Việc yêu cầu {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} 25hoặc {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} trong bản kê khai của bạn 26sẽ 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ể 27cấp nhiều quyền truy cập hơn những gì ứng dụng của bạn cần.</li> 28<li>Sử dụng 29<a href="{@docRoot}guide/topics/providers/document-provider.html">Khuôn khổ 30 Truy cập Kho lưu trữ</a> thường khiến người dùng chọn thư mục 31thô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 32một thư mục bên ngoài.</li> 33</ul> 34 35<p>Android N cung cấp một API mới được đơn giản hóa để truy cập 36các thư mục lưu trữ bên ngoài thường dùng. </p> 37 38<h2 id="accessing">Truy cập một Thư mục lưu trữ bên ngoài</h2> 39 40<p>Sử dụng lớp <code>StorageManager</code> để lấy thực thể 41<code>StorageVolume</code> phù hợp. Sau đó tạo một ý định bằng cách gọi phương thức 42<code>StorageVolume.createAccessIntent()</code> của thực thể đó. 43Sử 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 44tất cả các ổ đĩa, bao gồm các ổ đĩa media có thể tháo lắp, hãy sử dụng 45<code>StorageManager.getVolumesList()</code>.</p> 46 47<p>Đoạn mã sau là một ví dụ về cách mở thư mục 48<code>Pictures</code> trong bộ nhớ lưu trữ chính được chia sẻ:</p> 49 50<pre> 51StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE); 52StorageVolume volume = sm.getPrimaryVolume(); 53Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES); 54startActivityForResult(intent, request_code); 55</pre> 56 57<p>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 58cầ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:</p> 59 60<img src="{@docRoot}preview/images/scoped-folder-access-framed.png" srcset="{@docRoot}preview/images/scoped-folder-access-framed.png 1x, 61{@docRoot}preview/images/scoped-folder-access-framed_2x.png 2x" /> 62<p class="img-caption"><strong>Hình 1.</strong> Một ứng dụng yêu cầu 63truy cập tới thư mục Pictures.</p> 64 65<p>Nếu người dùng cấp quyền truy cập, hệ thống sẽ gọi phương thức ghi đè 66<code>onActivityResult()</code> của bạn với mã kết quả là 67<code>Activity.RESULT_OK</code> và dữ liệu ý định có chứa URI. Hãy sử dụng 68URI được cung cấp để truy cập thông tin thư mục, giống như sử dụng các URI 69được trả về bởi 70<a href="{@docRoot}guide/topics/providers/document-provider.html">Khuôn khổ 71 Truy cập Kho lưu trữ</a>.</p> 72 73<p>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 đè 74<code>onActivityResult()</code> của bạn với mã kết quả là 75<code>Activity.RESULT_CANCELED</code> và dữ liệu ý định có giá trị null.</p> 76 77<p class="note"><b>Lưu ý</b>: Lấy quyền truy cập tới một thư mục bên ngoài được chỉ định 78cũng sẽ cấp quyền truy cập tới các thư mục con thuộc thư mục đó.</p> 79 80<h2 id="removable">Truy cập một Thư mục trên phương tiện tháo lắp được</h2> 81 82<p>Để 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, 83trước hết, hãy thêm một {@link android.content.BroadcastReceiver} để lắng nghe 84thông báo {@link android.os.Environment#MEDIA_MOUNTED}, ví dụ:</p> 85 86<pre> 87<receiver 88 android:name=".MediaMountedReceiver" 89 android:enabled="true" 90 android:exported="true" > 91 <intent-filter> 92 <action android:name="android.intent.action.MEDIA_MOUNTED" /> 93 <data android:scheme="file" /> 94 </intent-filter> 95</receiver> 96</pre> 97 98<p>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 99{@link android.os.Environment#MEDIA_MOUNTED}. Thông báo này 100sẽ cung cấp một đối tượng <code>StorageVolume</code> trong dữ liệu ý định mà bạn có thể 101sử 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 102sẽ truy cập thư mục <code>Pictures</code> trên phương tiện có thể tháo lắp:</p> 103 104<pre> 105// BroadcastReceiver has already cached the MEDIA_MOUNTED 106// notification Intent in mediaMountedIntent 107StorageVolume volume = (StorageVolume) 108 mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME); 109volume.createAccessIntent(Environment.DIRECTORY_PICTURES); 110startActivityForResult(intent, request_code); 111</pre> 112 113<h2 id="best">Thực hành Tốt nhất</h2> 114 115<p>Khi có thể, hãy duy trì URI truy cập thư mục bên ngoài để bạn không phải 116lặ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 117<code>getContentResolver().takePersistableUriPermssion()</code> với 118URI truy cập thư mục. Hệ thống sẽ duy trì URI và các yêu cầu 119truy cập sau này sẽ trả về <code>RESULT_OK</code> và không hiển thị UI xác nhận cho 120người dùng nữa.</p> 121 122<p>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 123yê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 124người dùng không tốt.</p> 125