Grant Uri也读取了在浏览器中使用content:/// scheme打开的html链接的文件的权限

时间:2018-06-14 16:24:15

标签: android android-intent android-fileprovider

要在Web浏览器中打开文件,并避免使用Oreo中的FileUriExposedException,我使用FileProvider和临时URI权限正确共享文件。 问题是要打开的html文件包含指向另一个配套文件的链接,该文件可以与file:///[...]一起使用,并且可以在目标应用中读取外部内存的固定权限,但不会使用content:///[...]因为当然临时权限只授予第一个文件而不是第二个文件。

有没有办法将临时读取权限授予另一个文件?在用户选择他们实际想要使用的应用程序之前,无需手动将其他文件的权限授予每个合适的应用程序?

目前的代码,使用各种浏览器的迭代:

protected Uri getUriFromFile(File file)
{
    return FileProvider.getUriForFile(
            this,
            "com.whatever.example.fileprovider",
            file);
}

protected void openInWebBroser(File file, File linkedFile)
{   
    Uri uri = getUriFromFile(file);
    Uri linkedUri = getUriFromFile(linkedFile);

    // Firefox and html viewer
    Intent webIntent1 = new Intent(Intent.ACTION_VIEW);
    webIntent1.setDataAndType(uri, "text/html");
    webIntent1.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    // TODO somehow add also linkedUri, not to be open right now but to be added to permitted???

    // Chrome
    Intent webIntent2 = new Intent(Intent.ACTION_VIEW);
    webIntent2.setDataAndType(uri, "multipart/related");
    webIntent2.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    // Default android browser
    Intent webIntent3 = new Intent(Intent.ACTION_VIEW);         
    webIntent3.setDataAndType(uri, "text/html");
    webIntent3.setClassName("com.android.browser", "com.android.browser.BrowserActivity");
    webIntent3.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    if(getPackageManager().queryIntentActivities(webIntent1, 0).size() > 0)
    {
        Intent chooserIntent = Intent.createChooser(webIntent1, null);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { webIntent2, webIntent3 });          
        startActivity(chooserIntent);
    }
    else if(getPackageManager().queryIntentActivities(webIntent2, 0).size() > 0)
    {
        Intent chooserIntent = Intent.createChooser(webIntent2, null);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { webIntent3 });          
        startActivity(chooserIntent);
    }
    else if(getPackageManager().queryIntentActivities(webIntent3, 0).size() > 0)
    {
        Intent chooserIntent = Intent.createChooser(webIntent3, null);          
        startActivity(chooserIntent);
    }
    else
    {
        // ... error management
    }
}

1 个答案:

答案 0 :(得分:0)

好吧,没有答案,也没有更好的选择,我能想到的最好的办法就是预先授权任何可用的浏览器读取链接文件。

对于initialize' 2018-07-30T13:42:29.385084+00:00 app[web.1]: from /app/config.ru:in,尽管文档中坚持要求您调用它,但从原始应用程序中调用它似乎不正确(例如,在<main>' 2018-07-30T13:42:29.385087+00:00 app[web.1]: from /app/vendor/bundle/ruby/2.3.0/gems/rack-1.4.7/lib/rack/builder.rb:40:in时在parse_file' 2018-07-30T13:42:29.385090+00:00 app[web.1]: from /app/vendor/bundle/ruby/2.3.0/gems/rack-1.4.7/lib/rack/server.rb:200:in中调用它) :如果在浏览器仍处于打开状态时关闭了原始应用程序会发生什么? (使用该意图时,当目标应用程序展开堆栈时,权限将被吊销。)文档指出,该权限在设备重启后才有效。这似乎比其他选择要好。意见?

是否有一种方法只能针对用户实际选择的应用程序执行? (无需重新实现整个选择器。)

app'
2018-07-30T13:42:29.385095+00:00 app[web.1]: from /app/vendor/bundle/ruby/2.3.0/gems/rack-1.4.7/lib/rack/server.rb:254:in