如何使用psented的棒棒糖新的SD卡访问API $ P $? [英] How to use the new SD-Card access API presented for Lollipop?

查看:366
本文介绍了如何使用psented的棒棒糖新的SD卡访问API $ P $?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

到SD卡

在Android的奇巧(4.4),谷歌已经获得相当的限制。

由于Android的棒棒堂(5.0),开发人员可以使用新的API,要求用户确认,允许访问特定的文件夹,写上的 此谷歌团后

问题

该职位将引导您游览2网站:

  • <一个href="https://android.googlesource.com/platform/development/+/android-5.0.0_r2/samples/Vault/src/com/example/android/vault/VaultProvider.java#258">https://android.googlesource.com/platform/development/+/android-5.0.0_r2/samples/Vault/src/com/example/android/vault/VaultProvider.java#258

这看起来像一个内部的例子(也许要在API演示后表示),但它是相当难以明白是怎么回事。

  • <一个href="http://developer.android.com/reference/android/support/v4/provider/DocumentFile.html">http://developer.android.com/reference/android/support/v4/provider/DocumentFile.html

这是新的API的正式文件,但它并没有告诉如何使用它足够的细节。

下面是它告诉你:

  

如果你真的需要完全访问的文档的整个子树,   通过启动ACTION_OPEN_DOCUMENT_TREE让用户选择一个开始   目录。然后通过产生的getData()为fromTreeUri(背景下,   乌里)开始与所述用户选定的树的工作

     

当您浏览DocumentFile实例的树,你可以随时使用   的getURI()来获取开放的再presenting为基础文档   该对象,用于openInputStream(URI),等等。

使用      

要简化运行奇巧设备的code或更早的版本,你可以   使用FROMFILE(文件),它模拟一个DocumentsProvider的行为。

的问题

我对新的API几个问题:

  1. 如何真正使用它?
  2. 据后,操作系统会记住该应用程序被赋予访问文件/文件夹的权限。你如何检查是否可以访问文件/文件夹?是否有一个函数,返回我的文件/文件夹列表中,我可以访问?
  3. 你是如何处理的奇巧这个问题?它是支持库的一部分?
  4. 有没有设置屏幕,显示操作系统哪些应用程序可以访问哪些文件/文件夹?
  5. 如果一个应用程序被安装为多个用户在同一台​​设备上会发生什么?
  6. 有没有其他的文档/教程这个新的API?
  7. 可以权限被撤销?如果是这样,是否有东西被发送到应用程序?
  8. 意向
  9. 将为请求允许递归工作在选定文件夹?
  10. 请问使用权限还允许向用户提供多重选择由用户选择的机会呢?抑或是应用程序需要明确告诉意图让该文件/文件夹?
  11. 有没有在模拟器的方式来尝试新的API?我的意思是,它有SD卡的分区,但它的作品作为主要外部存储,这样所有进入它已经给出(使用简单的权限)。
  12. 当用户更换SD卡与另外一个会发生什么
解决方案

很多很好的问题,让我们深入的:)

你如何使用它?

下面是与存储访问架构在奇巧交互的伟大的教程:

<一个href="https://developer.android.com/guide/topics/providers/document-provider.html#client">https://developer.android.com/guide/topics/providers/document-provider.html#client

在棒棒堂新的API的交互是非常相似的。要提示用户选择一个目录树的用户,你可以启动一个意图是这样的:

 意向意图=新的意图(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(意向,42);
 

然后在你的onActivityResult(),您可以通过用户挑选开放的新DocumentFile辅助类。这里有一个简单的例子,列出在拍摄目录中的文件,然后创建一个新文件:

 公共无效onActivityResult(INT申请code,INT结果code,意图resultData){
    如果(结果code == RESULT_OK){
        乌里treeUri = resultData.getData();
        DocumentFile pickedDir = DocumentFile.fromTreeUri(这一点,treeUri);

        //列出所有现有的回升目录中的文件
        对于(DocumentFile文件:pickedDir.listFiles()){
            Log.d(TAG,找到的文件+ file.getName()+,大小+ file.length());
        }

        //创建一个新的文件,并写入到它
        DocumentFile NEWFILE = pickedDir.createFile(text / plain的,我的小说);
        的OutputStream出= getContentResolver()openOutputStream(newFile.getUri())。
        out.write(很久很久以前......的GetBytes());
        out.close();
    }
}
 

返回的乌里DocumentFile.getUri()足够灵活,可以在不同的平台API来使用。例如,你可以使用共享 Intent.setData() Intent.FLAG_GRANT_READ_URI_PERMISSION

如果您要访问的开放的我们从本地code,你可以叫 ContentResolver.openFileDescriptor()然后用 ParcelFileDescriptor.getFd () detachFd()来获得一个传统的POSIX文件描述整数。

您如何检查,如果你可以访问文件/文件夹?

在默认情况下,这些URI返回通过存储访问框架的意图是的没有的持续跨越重启。该平台提供了坚持权限的能力,但你仍然需要采取权限,如果你想要它。在上面的例子中,你会打电话来:

  getContentResolver()。takePersistableUriPermission(treeUri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION |
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
 

您可以随时找出坚持资助的程序通过了 ContentResolver.getPersistedUriPermissions() API访问。如果您不再需要访问一个持续开放的,你可以用释放ContentResolver.releasePersistableUriPermission()

这是适用于奇巧?

没有,我们不能追溯添加新的功能,以旧版本的平台。

我可以看到哪些应用程序可以访问文件/文件夹?

目前旗下有没有用户界面,显示这一点,但你可以找到的授予开放的权限部分中的细节亚行外壳dumpsys活动的供应商输出。

如果一个应用程序被安装为多个用户在同一台​​设备上发生什么呢?

开放的权限授予被隔离在每个用户的基础上,就像所有其他的多用户的平台功能。也就是说,在两个不同的用户运行相同的应用程序没有overlaping或共享开放的权限授予。

可以权限被撤销?

背DocumentProvider可以随时撤销的许可,当一个基于云的文件被删除等。发现这些被撤销权限最常见的方式是当他们从 ContentResolver.getPersistedUriPermissions()上述消失。

权限都被撤销,每当应用程序的数据被清空,无论是应用程序所涉及的补助。

将为请求允许递归工作在选定文件夹?

是的,在 ACTION_OPEN_DOCUMENT_TREE 意图让你递归访问现有的和新创建的文件和目录。

这是否允许多选?

是的,多选择已经从奇巧的支持,你可以允许它通过设置 EXTRA_ALLOW_MULTIPLE 开始,当你的 ACTION_OPEN_DOCUMENT 意图。您可以使用 Intent.setType() EXTRA_MIME_TYPES 来缩小这种可以拿起文件类型:

<一个href="http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT">http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT

有没有在模拟器的方式来尝试新的API?

是的,主共享的存储设备应该出现在选取器,即使是在模拟器上。如果你的应用程序只使用了存储访问架构用于访问共享存储,您不再需要读/ WRITE_EXTERNAL_STORAG​​E 权限的所有的,可以将其删除或使用机器人:maxSdkVersion 功能,只要求他们在旧版本的平台

当用户更换SD卡与另一

会发生什么事?

当涉及物理介质,底层介质的UUID(例如FAT序列号)总是被烧到返回URI。该系统使用它来连接到用户原来选择的媒体,即使用户交换媒体的多个插槽之间左右。

如果在第二个卡用户掉期,则需要提示获得新卡。由于系统会记住每个UUID基础上补助,你会继续有$ P $到原卡pviously授予的访问,如果用户稍后重新插入它。

<一个href="http://en.wikipedia.org/wiki/Volume_serial_number">http://en.wikipedia.org/wiki/Volume_serial_number

Background

On Android Kitkat (4.4), Google has made access to the SD-card quite restricted.

As of Android Lollipop (5.0), developers can use a new API that asks the user to confirm to allow access to specific folders, as written on the this Google-Groups post .

The problem

The post directs you to visit 2 websites:

This looks like an inner example (perhaps to be shown on the API demos later), but it's quite hard to understand what's going on.

This is the official documentation of the new API, but it doesn't tell enough details about how to use it.

Here's what it tells you:

If you really do need full access to an entire subtree of documents, start by launching ACTION_OPEN_DOCUMENT_TREE to let the user pick a directory. Then pass the resulting getData() into fromTreeUri(Context, Uri) to start working with the user selected tree.

As you navigate the tree of DocumentFile instances, you can always use getUri() to obtain the Uri representing the underlying document for that object, for use with openInputStream(Uri), etc.

To simplify your code on devices running KITKAT or earlier, you can use fromFile(File) which emulates the behavior of a DocumentsProvider.

The questions

I have a few questions about the new API:

  1. How do you really use it?
  2. According to the post, the OS will remember that the app was given a permission to access the files/folders. How do you check if you can access the files/folders ? Is there a function that returns me the list of files/folders that I can access?
  3. How do you handle this problem on Kitkat? Is it a part of the support library?
  4. Is there a settings screen on the OS that shows which apps have access to which files/folders?
  5. What happens if an app is installed for multiple users on the same device?
  6. Is there any other documentation/tutorial about this new API ?
  7. Can the permissions be revoked ? If so, is there an intent that's being sent to the app?
  8. Would asking for the permission work recursively on a selected folder?
  9. Would using the permission also allow to give the user a chance of multiple selection by user's choice? Or does the app need to specifically tell the intent which files/folders to allow?
  10. Is there a way on the emulator to try the new API ? I mean, it has SD-card partition, but it works as the primary external storage, so all access to it is already given (using a simple permission).
  11. What happens when the user replaces the SD-card with another one?

解决方案

Lots of good questions, let's dig in. :)

How do you use it?

Here's a great tutorial for interacting with the Storage Access Framework in KitKat:

https://developer.android.com/guide/topics/providers/document-provider.html#client

Interacting with the new APIs in Lollipop is very similar. To prompt the user to pick a directory tree, you can launch an intent like this:

    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(intent, 42);

Then in your onActivityResult(), you can pass the user-picked Uri to the new DocumentFile helper class. Here's a quick example that lists the files in the picked directory, and then creates a new file:

public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    if (resultCode == RESULT_OK) {
        Uri treeUri = resultData.getData();
        DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);

        // List all existing files inside picked directory
        for (DocumentFile file : pickedDir.listFiles()) {
            Log.d(TAG, "Found file " + file.getName() + " with size " + file.length());
        }

        // Create a new file and write into it
        DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
        OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
        out.write("A long time ago...".getBytes());
        out.close();
    }
}

The Uri returned by DocumentFile.getUri() is flexible enough to use with may different platform APIs. For example, you could share it using Intent.setData() with Intent.FLAG_GRANT_READ_URI_PERMISSION.

If you want to access that Uri from native code, you can call ContentResolver.openFileDescriptor() and then use ParcelFileDescriptor.getFd() or detachFd() to obtain a traditional POSIX file descriptor integer.

How do you check if you can access the files/folders?

By default, the Uris returned through Storage Access Frameworks intents are not persisted across reboots. The platform "offers" the ability to persist the permission, but you still need to "take" the permission if you want it. In our example above, you'd call:

    getContentResolver().takePersistableUriPermission(treeUri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION |
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

You can always figure out what persisted grants your app has access to through the ContentResolver.getPersistedUriPermissions() API. If you no longer need access to a persisted Uri, you can release it with ContentResolver.releasePersistableUriPermission().

Is this available on KitKat?

No, we can't retroactively add new functionality to older versions of the platform.

Can I see what apps have access to files/folders?

There's currently no UI that shows this, but you can find the details in the "Granted Uri Permissions" section of adb shell dumpsys activity providers output.

What happens if an app is installed for multiple users on the same device?

Uri permission grants are isolated on a per-user basis, just like all other multi-user platform functionality. That is, the same app running under two different users has no overlaping or shared Uri permission grants.

Can the permissions be revoked?

The backing DocumentProvider can revoke permission at any time, such as when a cloud-based document is deleted. The most common way to discover these revoked permissions is when they disappear from ContentResolver.getPersistedUriPermissions() mentioned above.

Permissions are also revoked whenever app data is cleared for either app involved in the grant.

Would asking for the permission work recursively on a selected folder?

Yep, the ACTION_OPEN_DOCUMENT_TREE intent gives you recursive access to both existing and newly created files and directories.

Does this allow multiple selection?

Yep, multiple selection has been supported since KitKat, and you can allow it by setting EXTRA_ALLOW_MULTIPLE when starting your ACTION_OPEN_DOCUMENT intent. You can use Intent.setType() or EXTRA_MIME_TYPES to narrow the types of files that can be picked:

http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT

Is there a way on the emulator to try the new API?

Yep, the primary shared storage device should appear in the picker, even on the emulator. If your app only uses the Storage Access Framework for accessing shared storage, you no longer need the READ/WRITE_EXTERNAL_STORAGE permissions at all and can remove them or use the android:maxSdkVersion feature to only request them on older platform versions.

What happens when the user replaces the SD-card with another one?

When physical media is involved, the UUID (such as FAT serial number) of the underlying media is always burned into the returned Uri. The system uses this to connect you to the media that the user originally selected, even if the user swaps the media around between multiple slots.

If the user swaps in a second card, you'll need to prompt to gain access to the new card. Since the system remembers grants on a per-UUID basis, you'll continue to have previously-granted access to the original card if the user reinserts it later.

http://en.wikipedia.org/wiki/Volume_serial_number

这篇关于如何使用psented的棒棒糖新的SD卡访问API $ P $?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆