【问题标题】:Document-picker keeps showing up even though persistence is set (in SAF - Storage Access Framework)即使设置了持久性,文档选择器也会继续显示(在 SAF - 存储访问框架中)
【发布时间】:2016-12-21 15:49:52
【问题描述】:

使用 Android 6.0.1,API 23,

我成功地实现了从用户在 SAF 的文档选择器 (Storage Access Framework) 中选择的存储位置读取文件。

现在,我想使用 SAF 允许的 Persist permissions,以允许我的应用程序始终选择相同的文件(但不会一直弹出任何文档选择器窗口 [和子窗口])。

我以某种方式成功实现了 Persist-permissions(如 SAF-doc 所示)(...为此,请参阅下面的代码示例...) - 但是问题出现了:

  1. 尽管持久性许可工作 - 为什么文档选择器窗口不断弹出?一旦用户选择了文件 - 从这一刻起 - 我想简单地获取文件内容,而不需要任何选择器窗口进入前台。这可能吗?如果是,如何? (我可以说持久性权限在某种程度上起作用了,因为文件会立即被读取,而用户不必再次选择。但是这个讨厌的选择器窗口仍然不应该出现 - 或者是吗?)
  2. 即使我的应用程序关闭或停止,是否可以保持 SAF 持久性权限?如果是,怎么做?

这是获取文件内容的代码示例,包括我的持久化权限试用:

在 StorageClientFragment 类中:

public String locationFileContent;

public void performFileSearch() {
    Intent openDocumentIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    openDocumentIntent.addCategory(Intent.CATEGORY_OPENABLE);
    openDocumentIntent.setType("text/plain");
    openDocumentIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
    startActivityForResult(openDocumentIntent, READ_REQUEST_CODE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {

    if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        Uri uri = null;
        if (resultData != null) {
            uri = resultData.getData();

            // Here is my Persist-permission trial !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            getActivity().getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

            try {
                this.locationFileContent = readTextFromUri(uri);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

private String readTextFromUri(Uri uri) throws IOException {
    InputStream inputStream = getActivity().getContentResolver().openInputStream(uri);
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder stringBuilder = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        stringBuilder.append(line);
    }
    inputStream.close();
    return stringBuilder.toString();
}

在 MainActivity 中创建 Fragment:

StorageClientFragment storageClientFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        storageClientFragment = new StorageClientFragment();
        transaction.add(storageClientFragment, FRAGTAG);
        transaction.commit();
    }
}

当点击测试按钮时调用 FileSearch:

public void TestingButtonClicked(View view) {
    this.storageClientFragment.performFileSearch();
    String stringFileContent = this.storageClientFragment.locationFileContent;
    Toast.makeText(this, "Back in Main, Content = " + stringFileContent, Toast.LENGTH_SHORT).show();
}

上面的代码运行良好。但同样,我怎样才能阻止 SAF 文档选择器窗口一直显示(即使设置了持久权限)?

【问题讨论】:

    标签: android file-permissions persistent-storage storage-access-framework


    【解决方案1】:

    为什么文档选择器窗口不断弹出?

    大概是因为您一直在启动ACTION_OPEN_DOCUMENT 活动。如果您不想让用户选择文档,请不要启动此活动。

    我想简单地获取文件内容,而不需要任何选择器窗口进入前台。这可能吗 ?如果是,如何??

    与您最初获取内容的方式相同:将Uri 传递给openInputStream() ContentResolver

    如果您使用takePersistableUriPermissions() 来实现对内容的长期访问,那么您的工作仍然是保持Uri。这与此类事情在其他环境中的工作方式没有显着不同(例如,记住桌面操作系统程序的用户本地文件路径历史记录)。

    由于Uri 可以轻松地与String 相互转换,因此将Uri 保存在某个位置(数据库、SharedPreferences 或其他文件)并不是特别困难。

    即使我的应用程序关闭或停止,是否可以保持 SAF 持久性许可?如果是,如何??

    takePersistableUriPermission(),你已经实现了。

    【讨论】:

    • 谢谢!这说明了很多。这对我来说都是全新的,我不知道 URI 是唯一的并且可以保留(例如使用 SharedPrefs)。如果我理解正确,takePersistableUriPermission() 会以某种方式对隐藏的安全标志进行双重检查,并告诉应用程序可以继续使用(或者,如果用户从未在文档选择器中选择任何内容)。相当不错 - 所有这些。我将尝试实现这一点。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多