page.title=作用域目录访问 page.keywords=Preview、SDK、作用域目录访问 page.tags=Android N @jd:body
应用(如照片应用)通常只需要访问外部存储中的特定目录,例如 Pictures
目录。
现有的外部存储访问方法未经专门设计,无法轻松地为这些类型的应用提供目标目录访问。
例如:
Android N 提供简化的全新 API 以访问通用外部存储目录。
使用 StorageManager
类获取适当的
StorageVolume
实例。然后,通过调用该实例的
StorageVolume.createAccessIntent()
方法创建一个 Intent。使用此 Intent 访问外部存储目录。
若要获取所有可用卷的列表,包括可移动介质卷,请使用
StorageManager.getVolumesList()
。
如果您有关于特定文件的信息,使用 StorageManager.getStorageVolume(File)
来获得包含该文件的 StorageVolume
。
调用在 StorageVolume
上的 createAccessIntent()
以访问文件的外部存储目录。
在二级卷(例如外部 SD 卡)上,当调用 StorageVolume.createAccessIntent()
以请求访问整个卷,而不是特定目录时,传入“null”。如果您向主要卷传入“null”,或者如果您传入无效的目录名,StorageVolume.createAccessIntent()
将返回“null”。
以下代码段展示如何在主要共享存储中打开Pictures
目录:
StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE); StorageVolume volume = sm.getPrimaryVolume(); Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES); startActivityForResult(intent, request_code);
系统尝试授予对外部目录的访问权限,并使用一个简化的 UI 向用户确认访问权限(如果需要):
如果用户授予访问权限,则系统会调用
onActivityResult()
重写方法,且结果代码为
Activity.RESULT_OK
,Intent 数据包含 URI。使用提供的 URI 访问目录信息,与使用存储访问框架返回的 URI 类似。
如果用户不授予访问权限,则系统会调用
onActivityResult()
重写方法,且结果代码为
Activity.RESULT_CANCELED
,Intent 数据为 null。
注:获得特定外部目录的访问权限也会获得该目录中子目录的访问权限。
若要使用作用域目录访问来访问可移动介质上的目录,首先要添加一个用于侦听 {@link android.os.Environment#MEDIA_MOUNTED} 通知的 {@link android.content.BroadcastReceiver},例如:
<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>
当用户装载可移动介质时,如 SD 卡,系统将发送一则
{@link android.os.Environment#MEDIA_MOUNTED} 通知。此通知在 Intent 数据中提供一个 StorageVolume
对象,您可用它访问可移动介质上的目录。
以下示例访问可移动介质上的 Pictures
目录:
// 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);
请尽可能保留外部目录访问 URI,这样即不必重复要求用户授予访问权限。
在用户授予访问权限后,使用目录访问 URI 调用
getContentResolver().takePersistableUriPermssion()
。
系统将保留此 URI,后续的访问请求将返回 RESULT_OK
,且不会向用户显示确认 UI。
如果用户拒绝授予外部目录访问权限,请勿立即再次请求访问权限。 一再不停地请求访问权限会导致非常差的用户体验。 如果用户拒绝了一项请求,而应用再次请求访问,UI 会显示一个 Don't ask again 复选框:
如果用户选择 Don't ask again 并拒绝请求,您的应用向指定目录提出的所有未来请求都将被自动拒绝,并且将不会有请求 UI 呈现给用户。