Skip to content

Most visited

Recently visited

navigation

使用作用域目录访问

应用(如照片应用)通常只需要访问外部存储中的特定目录,例如 Pictures 目录。现有的外部存储访问方法未经专门设计,无法轻松地为这些类型的应用提供定向目录访问。例如:

Android 7.0 提供简化的 API 来访问常见的外部存储目录。

访问外部存储目录

使用 StorageManager 类获取适当的 StorageVolume 实例。然后,通过调用该实例的 StorageVolume.createAccessIntent() 方法创建一个 intent。使用此 intent 访问外部存储目录。要获取所有可用卷的列表,包括可移动介质卷,请使用 StorageManager.getStorageVolumes()

如果您有关于特定文件的信息,请使用 StorageManager.getStorageVolume(File) 获取包含该文件的 StorageVolume。调用此 StorageVolume 上的 createAccessIntent() 以访问文件的外部存储目录。

在次要卷(例如外部 SD 卡)上,调用 createAccessIntent() 以请求访问整个卷而不是特定目录时将传入“null”。如果您向主要卷传入“null”,或者如果您传入无效的目录名,createAccessIntent() 将返回“null”。

以下代码段展示了如何在主要共享存储中打开 Pictures 目录:

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

系统尝试授予对外部目录的访问权限,并使用一个简化的 UI 向用户确认访问权限(如果需要):

图 1. 一个请求访问 Pictures 目录的应用。

如果用户授予访问权限,系统会调用 onActivityResult() 替换方法(结果代码为 RESULT_OK),以及包含 URI 的 intent 数据。使用提供的 URI 访问目录信息,与使用存储访问框架返回的 URI 类似。

如果用户不授予访问权限,系统将调用onActivityResult() 替换方法(结果代码为 RESULT_CANCELED),以及空 intent 数据。

获得特定外部目录的访问权限也会获得该目录中子目录的访问权限。

访问可移动介质上的目录

要使用作用域目录访问来访问可移动介质上的目录,首先请添加一个用于侦听 MEDIA_MOUNTED 通知的 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 卡)时,系统将发送一则 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,这样就不必重复要求用户授予访问权限。在用户授予访问权限后,调用 getContentResolver(),在返回 ContentResolver 后,使用目录访问 URI 调用 takePersistableUriPermission()。系统将保留此 URI,后续的访问请求将返回 RESULT_OK,且不会向用户显示确认 UI。

如果用户拒绝授予外部目录访问权限,请勿立即再次请求访问权限。反复不停地请求访问权限会导致糟糕的用户体验。如果用户拒绝了一项请求,而应用再次请求访问权限,UI 会显示一个 Don't ask again 复选框:

图 1. 应用第二次请求访问可移动介质。

如果用户选择 Don't ask again 并拒绝请求,您的应用向给定目录提出的所有未来请求都将被自动拒绝,并且将不会有请求 UI 呈现给用户。

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)