我必须遵循以下情况:
我有一个已经存在的远程网页,我想开发一个使用此页面的应用程序。
到现在为止还挺好。当我启动应用时,会加载本地index.html
并将其重定向(window.open target: _self
)到外部网站。该网站在phonegap webview中打开。在外部网站上,我添加了cordova.js
以访问本机phonegap API。但它无法正常工作。正确触发 deviceReady 事件,但我无法访问phonegap API,例如navigator.camera。
我如何完成它,才能访问API?
请不要评论它会被AppStore等拒绝
感谢您的帮助!
答案 0 :(得分:12)
嗯,对我来说,解决方案是多个来源的混合,但大多数解决方案都被发现here。
您应该做的是以下内容:
将config.xml
定义为直接指向远程index.html
。
<content src="http://your-remote-location/index.html" />
在index.html
对本地Android设备资源的任何引用前加上一些唯一的前缀,如**injection**
。例如,对于cordova.js
,您会想出类似的内容:
<script type="text/javascript" src="**injection**www/cordova.js"></script>
在以下位置查找SystemWebViewClient.java
:your-project-location\platforms\android\CordovaLib\src\org\apache\cordova\engine
。
在顶部类的私有成员部分添加以下枚举声明:
private enum WebExtension {
PNG, MP3, MP4, TTF, SVG, JS, ICO, HTML, CSS, EOT, WOFF, JSON;
}
找到shouldInterceptRequest
方法并在try {
行之后添加以下内容:
if(url != null && url.contains(INJECTION_TOKEN)) {
String assetPath = url.substring(url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length(), url.length());
try {
String mimeType = "text/plain";
String ext = assetPath.substring(assetPath.lastIndexOf(".") + 1, assetPath.length());
WebExtension extension = WebExtension.valueOf(ext.toUpperCase());
switch(extension) {
case PNG:
mimeType = "image/png";
break;
case MP3:
mimeType = "audio/mpeg";
break;
case MP4:
mimeType = "video/mp4";
break;
case TTF:
mimeType = "application/x-font-ttf";
break;
case SVG:
mimeType = "image/svg+xml";
break;
case JS:
mimeType = "application/javascript";
break;
case ICO:
mimeType = "image/x-icon";
break;
case HTML:
mimeType = "text/html";
break;
case CSS:
mimeType = "text/css";
break;
case EOT:
mimeType = "application/vnd.ms-fontobject";
break;
case WOFF:
mimeType = "application/x-font-woff";
break;
case JSON:
mimeType = "application/json";
break;
}
WebResourceResponse response = new WebResourceResponse(
mimeType,
"UTF-8",
parentEngine.webView.getContext().getAssets().open(assetPath)
);
return response;
} catch (IOException e) {
e.printStackTrace(); // Failed to load asset file
}
}
所有资源请求的结果将是拦截每个资源请求,如果它包含**injection**
字符串,它将减少资源位置并从本地设备位置请求它应用程序正在运行mimeType是应用浏览器以正确方式加载资源所必需的。
希望它有所帮助。
答案 1 :(得分:9)
在远程站点中包含cordova.js脚本会很棘手,因为每个平台都有不同的cordova.js。您可以修改服务器,以便它根据用户代理返回正确的cordova.js,但这也很棘手,因为当您从移动浏览器查看网站时它将包含此脚本,这是不可取的,因为javascript错误可能是向用户显示。从台式计算机查看网站时,不应包含cordova.js。
在我看来,您有一个本地网页(包含cordova脚本),然后从那里切换到远程页面(还包括脚本)。我不确定这个页面更改是否会起作用。如果它有效,您可能必须等待第二个deviceready事件。
但您可以将远程站点页面设置为cordova应用程序中的根页面,无需中间的“加载程序”页面。只需在config.xml文件中设置它:
<content src="http://your.website.fake/index.html" />
您需要确保允许在应用中加载您的网站。在同一个文件中,您应该添加:
<access origin="http://your.website.fake" subdomains="true"/>
答案 2 :(得分:9)
这个插件解决了这个问题,而无需自己编写Android解决方案。
https://www.npmjs.com/package/cordova-plugin-remote-injection
https://github.com/TruckMovers/cordova-plugin-remote-injection
远程注入插件允许远程站点在您的cordova应用程序中加载时与cordova的JavaScript API进行交互。
将cordova和安装的插件JS注入任何远程浏览页面的webview,允许他们作为打包的cordova应用程序访问cordova对象及其插件。
支持iOS和Android平台。
我测试了它,它工作得很好。您唯一需要记住的是,您需要等待cordova准备好,如下所示:
<html>
<head>
</head>
<body>
<script>
document.addEventListener("deviceready", function() {
document.write("Now you can use plugins");
}, false);
</script>
</body>
</html>
答案 3 :(得分:7)
我也遇到过这个问题,而且在config.xml(内容和访问标签)中更改内容并不起作用。我在手机上运行时检查了应用程序,发现当我加载远程站点时,有些文件丢失了。
首先,您可以找到平台文件夹中每个平台的名为 cordova_plugins.js 的文件。然后你还需要一些特定于插件的文件。您可以通过构建并从那里提取它们来找到它们。对于android,路径如下APK / assets / www / plugins。只需复制服务器上的内容即可。
注意:您还可以在平台文件夹中找到插件特定文件,但它们不完整,因为它们缺少cordova.define(&#34; ...开头)这导致必需和模块未定义,所以只需进行构建并从那里获取它们。
答案 4 :(得分:0)
这是Cordova / PhoneGap强加的限制here:
if (startFilePath == nil) {
loadErr = [NSString stringWithFormat:@"ERROR: Start Page at '%@/%@' was not found.", self.wwwFolderName, self.startPage];
NSLog(@"%@", loadErr);
self.loadFromString = YES;
appURL = nil;
}
我过去禁用了此检查,以便让Cordova使用非本地文件地址。
答案 5 :(得分:0)
我已经努力让它工作很长时间才能进行phoneGap快速调试,但是如果没有将cordova.js与应用程序(不在远程位置)一起使用,就无法找到使API工作的方法。 / p>
我不知道为什么这不起作用。如果你知道内部工作,我期待听到它......
我尝试的最后一件事是在主html中放置100%x 100%iframe并在同一文档中加载本地cordova.js。然后我就可以使用API,但iOS上存在一些扩展问题,这是另一个问题......
我不记得我实施和编程的确切方式,但如果我能找到它,我会编辑。
答案 6 :(得分:0)
最简单的工作解决方案,允许从远程https页面加载本地文件而不会出现混合内容错误:
对于android:使用https://developer.android.com/reference/android/webkit/WebSettings.html#MIXED_CONTENT_ALWAYS_ALLOW)禁用混合内容策略
对于ios:我向文件插件提交了PR,该插件解决了ios上的混合内容问题:apache / cordova-plugin-file#296固定版本位于:https://github.com/guylando/cordova-plugin-file如果您加载远程站点在网络视图上https://example.com,然后它允许使用URL:https://example.com/cdvfile/bundle/www/cordova.js而不是cdvfile://localhost/bundle/www/cordova.js来访问本地文件,从而解决了混合内容问题