我们使用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。
我们没有使用FileProvider解决这个errorUrl问题,在cordova上也没有发现任何投诉或解决方案。
您熟悉此问题和解决方案吗? 我们的资产也位于远程服务器以及插件的js文件中,因此我们无法使用'cordova-plugin-network-information'的脱机事件,因为它的js文件不是'如果手机离线,则尚未加载。
谢谢!
答案 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
}
}