I'm writing an application for iPad using PhoneGap and I would like to load an external URL without triggering Safari or using internal web browser like ChildBrowser.
I'm using the PhoneGap iPad/iPhone sample project and I tried different approaches. In the onBodyLoad() function I added:
window.location.href('http://www.wordreference.com');
but this line opens the link using a new Safari window.From that point is not possible to come back in PhoneGap
Afterwards, I tried with an AJAX request substituting the content of the page using document.write
function loadHTML(url, timeout) {
if (timeout == undefined)
timeout = 10000;
var req = new XMLHttpRequest();
var timer = setTimeout(function() {
try {
req.abort();
} catch(e) {}
navigator.notification.loadingStop();
},timeout);
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status < 300) {
clearTimeout(timer);
var html = req.responseText;
//just a debug print
alert(html);
document.write(html);
}
navigator.notification.loadingStop();
delete req;
}
};
req.open('GET', url, true);
req.send();
}
Now, calling from inside onBodyLoad():
loadHTML('http://www.wordreference.com',10000);
Opens the link in the PhoneGap Container,which is fine. The point is that I want to load a dynamic page written in Python
loadHTML('http://www.mysite.com/cgi-bin/index.py',10000)
At this point Safari is not called but a black page in the PhoneGap container is displayed!!
I want to point out that the link is perfectly working if I type it in Safari( I cannot report it for privacy issues).
Could be it a problem related to some kind of needed permission???
I found something similar relative to PhoneGap for BlackBerry and the proposed solution was to modify a config.xml file with
<access subdomains="true" uri="http://www.mysite.com/" />
I tried to add this tag directly in my index.html but it doesn't work.
Is there any similar approach for iPhone??
Thanks a lot
I think I've found the solution,
in the PhoneGap Application Delegate .m file {YourProject}AppDelegate.m, modify the method:
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
}
with
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];
if ([[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) {
return YES;
}
else {
return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
}
}
This will open all the external links within the PhoneGap container!!!
ps. Around you will find references to this link but I think it doesn't work for app written using the 0.9.5 version,since Safari gets opened for external links by default.
For people having this problem in Android:
I don't know about earlier versions, but in PhoneGap 1.1.0 you can create a file called res/xml/phonegap.xml and list the domains which should not be opened in the external browser.
From DroidGap.java:
/**
* Load PhoneGap configuration from res/xml/phonegap.xml.
* Approved list of URLs that can be loaded into DroidGap
* <access origin="http://server regexp" subdomains="true" />
* Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
* <log level="DEBUG" />
*/
private void loadConfiguration() {
[...]
Example phonegap.xml:
<?xml version="1.0" encoding="UTF-8"?>
<phonegap>
<access origin="http://stackoverflow.com" subdomains="true" />
</phonegap>
This works - thanks Claus. Maybe some apps need to be more discriminate than just "http" and "https".
I did a similar thing with phonegap android, see below. Provide an interface (which I call EXTERNALLINK here), call loadExternalLink from javascript, then load that url into the current WebView. I'm no expert, but seems to work for me and just for the links you want it to be applied to.
ACTIVITY:
public class AndroidActivity extends DroidGap {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try
{
super.loadUrl("file:///android_asset/www/index.html");
this.appView.addJavascriptInterface(new JavaScriptInterface(), "EXTERNALLINK");
}
catch(Exception lException)
{
throw new RuntimeException("hello hello", lException);
}
}
class JavaScriptInterface
{
public void loadExternalLink(String lUrl)
{
try
{
loadUrl(lUrl);
}
catch(Exception lEx)
{
int i = 0;
}
}
}
}
JAVASCRIPT CALL EXAMPLE:
window.EXTERNALLINK.loadExternalLink("http://www.google.com");
In Android, to work around the problem of the screen going black during page transitions, as of PhoneGap 1.1.0, you can put:
super.setIntegerProperty("backgroundColor", Color.WHITE);
super.setStringProperty("loadingPageDialog", "Loading page...");
before super.loadUrl in the onCreate() method of your DroidGap Activity.
Here is a reference to the PhoneGap discussion forum that has the details:
http://comments.gmane.org/gmane.comp.handhelds.phonegap/11491
In Android you can make external links to open inside the webview by setting
super.setBooleanProperty("loadInWebView", true);
before super.loadUrl in your DroidGap Activity.
That would make every external link to open in the webview. If you want to open only certain domains in the webview use addWhiteListEntry instead. Example:
addWhiteListEntry("mydomain.com", true);