Java Phonegap/Cordova应用程序在Jelly Bean中中断-访问控制允许Origin和SetAllowUniversalAccessFromFileURL
我已经用Cordova(又名Phonegap)为Android开发了*一年多了,我试图让我的应用程序可以在Jelly Bean中运行,但我遇到了以下错误:Java Phonegap/Cordova应用程序在Jelly Bean中中断-访问控制允许Origin和SetAllowUniversalAccessFromFileURL,java,android,cordova,android-websettings,Java,Android,Cordova,Android Websettings,我已经用Cordova(又名Phonegap)为Android开发了*一年多了,我试图让我的应用程序可以在Jelly Bean中运行,但我遇到了以下错误: XMLHttpRequest cannot load http://127.0.0.1:40582/[somerandomstring]. Origin null is not allowed by Access-Control-Allow-Origin. at null:1 (以及任何后续ajax请求使用localhost或file://
XMLHttpRequest cannot load http://127.0.0.1:40582/[somerandomstring]. Origin null is not allowed by Access-Control-Allow-Origin. at null:1
(以及任何后续ajax请求使用localhost或file://)时出现的类似错误)
为了测试,我在访问控制允许源代码部分中授予对config.xml中所有内容的访问权
<access origin="*"/>
<access origin="http://127.0.0.1*"/>
--这也来自org.apache.cordova.CordovaWebView
// Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
// while we do this
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
Level16Apis.enableUniversalAccess(settings);
// Wrapping these functions in their own class prevents warnings in adb like:
// VFY: unable to resolve virtual method 285: Landroid/webkit/WebSettings;.setAllowUniversalAccessFromFileURLs
@TargetApi(16)
private static class Level16Apis {
static void enableUniversalAccess(WebSettings settings) {
settings.setAllowUniversalAccessFromFileURLs(true);
}
}
很高兴科尔多瓦尝试了改变,但不幸的是,这不起作用
在这些SO线程中,我找到了一个常见的解决方案,只需按如下方式更改设置:
if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
super.appView.getSettings().setAllowUniversalAccessFromFileURLs(true);
}
现在我得到以下警告:
Call requires API level 16 (current min is 8)
android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs
以下是我的AndroidManifest.xml中api的内容
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />
为什么它要求我将minSdkVersion更改为16,而不是遵循targetSdkVersion的16
想法
注意事项:我目前正在使用Cordova 2.0、Eclipse Indigo SR2(所有最新更新)、Android SDK(所有最新更新)、Windows 7 Home(所有最新更新)、Java 7 Update 7。好的,所以经过大量的搜索、猜测和检查,我找到了一个可行的解决方案 我必须为setAllowUniversalAccessFromFileURLs调用创建一个单独的函数。。。这修复了TargetApi问题,但在JellyBean上出现了另一个问题,它无法连接到我在loadURL调用中的文件,因此我必须重写onReceivedError函数。下面是我的结果代码:
package com.MyUniqueDomain.MyUniquePackage;
import android.annotation.TargetApi;
import android.os.Bundle;
import org.apache.cordova.*;
public class MainActivity extends DroidGap {
private int retryCount = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setStringProperty("loadingDialog", "Please wait -- loading...");
super.init();
if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
fixJellyBeanIssues();
}
super.loadUrl("file:///android_asset/www/index.html");
}
@TargetApi(16)
protected void fixJellyBeanIssues() {
System.out.println(super.appView.toString());
try {
super.appView.getSettings().setAllowUniversalAccessFromFileURLs(true);
} catch(NullPointerException e) {
System.out.println(e.toString());
}
}
// catch an error and if try again 1x or quit
@Override
public void onReceivedError( int errorCode, String description, String failingUrl)
{
if(retryCount < 3) {
retryCount++;
System.out.println("Connection failed, trying again. Retry Count: "+retryCount);
super.loadUrl("file:///android_asset/www/index.html");
} else {
System.out.println("Sorry, it failed three times so I give up.");
super.loadUrl("file:///android_asset/www/fail.html");
}
return;
}
}
package com.MyUniqueDomain.MyUniquePackage;
导入android.annotation.TargetApi;
导入android.os.Bundle;
导入org.apache.cordova.*;
公共类MainActivity扩展了DroidGap{
private int retryCount=0;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
super.setStringProperty(“加载对话框”,“请稍候--加载…”);
super.init();
if(android.os.Build.VERSION.SDK\u INT>android.os.Build.VERSION\u code.ICE\u SANDWICH\u MR1){
固定胶状物();
}
super.loadUrl(“file:///android_asset/www/index.html");
}
@塔吉塔皮(16)
受保护的空洞固定{
System.out.println(super.appView.toString());
试一试{
super.appView.getSettings().setAllowUniversalAccessFromFileURLs(true);
}捕获(NullPointerException e){
System.out.println(例如toString());
}
}
//捕获错误并重试或退出
@凌驾
接收错误时公共无效(输入错误代码、字符串描述、字符串失败URL)
{
如果(retryCount<3){
retryCount++;
System.out.println(“连接失败,重试。重试计数:”+retryCount);
super.loadUrl(“file:///android_asset/www/index.html");
}否则{
System.out.println(“对不起,它失败了三次,所以我放弃了。”);
super.loadUrl(“file:///android_asset/www/fail.html");
}
返回;
}
}
清单中的目标SDK版本是什么?我想我已经找到了。这并不理想,但至少是可行的。谢谢你的帮助。你能给我一个复制场景吗?我知道你已经解决了这个问题,但我们不希望框架中出现这个错误。从Phonegap.com下载Phonegap/Cordova 2.0,解压缩zip文件。将“示例”项目从lib/Android/目录复制到Eclipse工作区目录。在Eclipse中,进入文件->新建->其他,然后在向导中展开Android并选择“现有代码中的Android项目”,点击下一步,浏览到示例项目,单击“完成”。在文本编辑器中编辑“AndroidManifest.xml”,将android:targetSdkVersion=“16”添加到uses sdk标记中。编辑“project.properties”并将目标api更改为16。创建运行API 16的AVD。在该AVD中以应用程序的形式运行项目。检查logcat以查看XMLHttpRequest错误…示例应用程序仍显示为加载,但功能不全。此外,如果您添加任何Phonegap/Cordova调用以将资产读/写到应用程序中,它将失败,并出现与上述OP中所述相同的XMLHttpRequest错误。如果你想看到一些具体的例子,我很乐意将它们通过电子邮件发送给你或通过其他方法与你分享。幸运的是,你不需要在2.1.0中跳过这些障碍,因为该版本的bug已经修复。它工作得非常完美!谢谢我唯一需要改变的是@TargetApi(Build.VERSION\u CODES.JELLY\u BEAN)的@TargetApi(16)
+1为了救我的命,非常感谢:)这个答案对我来说非常有效