0

使用 Android 6.0.1,API 23,

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

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

我以某种方式成功实现了 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();
}

创建 Fragment 在 MainActivity 中完成:

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 文档选择器窗口一直显示(即使设置了持久权限)?

4

1 回答 1

0

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

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

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

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

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

由于 aUri可以简单地与 a 相互转换String,因此保存Uri某处(数据库SharedPreferences、 或其他文件)并不是特别困难。

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

takePersistableUriPermission(),正如您已经实施的那样。

于 2016-08-15T12:36:27.737 回答