带有file:// URI的Cordova errorUrl抛出FileUriExposedException

时间:2018-08-04 17:10:19

标签: cordova offline

我们使用Cordova已有数年,并且始终在config.xml上使用ErrorUrl首选项来指向应用程序捆绑包中的html页面。例如: <preference name="ErrorUrl" value="file:///android_asset/www/offline.html" />

此页面是在加载应用程序且没有Internet连接或远程服务器资产不可用时显示的,而不是常规错误页面/弹出窗口。 (如cordova文档所述-“如果设置,将在应用程序中出现错误时显示引用的页面,而不是标题为“ Application Error”的对话框。”)

现在,我们正在调整android应用程序以支持Google请求的最新目标API,并且当手机处于离线状态时运行我们的应用程序时,cordova会尝试转到该offline.html页面,但我们有一个例外- android.os.FileUriExposedException:file:///android_asset/www/offline.html通过Intent.getData()在应用程序之外公开

这是由于Android Nougat 7.0的更改所致:

https://developer.android.com/about/versions/nougat/android-7.0-changes#permfilesys 其中提到:

在包域之外传递file:// URI可能会使接收者无法访问。因此,尝试传递file:// URI会触发FileUriExposedException。建议共享私有文件内容的方法是使用FileProvider。

我也发现了这一点: https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en

我们没有使用FileProvider解决这个errorUrl问题,在cordova上也没有发现任何投诉或解决方案。

您熟悉此问题和解决方案吗? 我们的资产也位于远程服务器以及插件的js文件中,因此我们无法使用'cordova-plugin-network-information'的脱机事件,因为它的js文件不是'如果手机离线,则尚未加载。

谢谢!

1 个答案:

答案 0 :(得分:1)

我最终在WhiteListPlugin上通过以下变通方法解决了该问题,而无需接触cordova来源。

如果电话处于脱机状态,则CordovaActivity会调用onReceivedError(),然后尝试将该URL加载到CordovaWebViewImple.showWebPage()中。 在此方法中,它将调用loadUrlIntoView(),并且错误页面已成功加载。

问题在于,在此之后,是否存在检查(!pluginManager.shouldOpenExternalUrl(errorUrl))。 如果应该从外部打开页面(在我的情况下是真的),它将使用Intent启动一个活动,该活动带有此'file://'uri,最终会引发异常FileUriExposedException。

解决方案是修改WhiteListPlugin,shouldOpenExternalUrl方法,以将false返回到此特定的errorUrl值,以避免也有意打开它。

@Override
    public Boolean shouldOpenExternalUrl(String url) {

        if (url.equals("file:///android_asset/www/offline.html")){
            return false;
        }
        else { // Original code
            if (allowedIntents.isUrlWhiteListed(url)) {
                return true;
            }
            return null; // Default policy
        }
    }