I have a website that I want to enhance on mobiles with a hybrid app. Ideally the app would load the remote site over http but load the platform specific code locally. I've tried to set up a Cordova project to do this but am having lots of trouble. Cordova 4.3.1, Cordova Android 3.7.2 on a Nexus 7 Android 4.4.4 has been my environment. (The google maps plugin is for Cordova Android < 4.)
If I try to load file:///android_assets/www/cordova.js from an http site, chromium says Not allowed to load local resource. I tried to set up a local URL scheme but don't know what android-specific code to put where.
Is this the right way to make a hybrid app? Is there a cordova plugin to allow loading file: from http:?
I also tried using an iframe and passing messages to indicate cordova is enabled and which plugins are installed, but I don't want to deal with having the http server re-serve the same js files that are already available locally.
I also thought to download the website and access it over file: but I imagine I will have the same problem trying to access http resources.
I am able to load local cordova.js on remote html using cordova-plugin-file (cdvfile://) plugin .
Add cordova-plugin-file plugin to your cordova project
https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/
Confirm cdvfile URI for cordova.js using below sample code(Android example)
checkCordovaJSPath('file:///android_asset/www/cordova.js');
function checkCordovaJSPath(jsUri) {
window.resolveLocalFileSystemURL(jsUri, function success(fileEntry){
console.log("got cordova.js file: " + fileEntry.fullPath);
console.log('cordova.js cdvfile URI: ' + fileEntry.toInternalURL());
});
}
Load cordova.js using cdvfile://localhost on remote html.
<script type="text/javascript" src="cdvfile://localhost/assets/www/cordova.js"/>
I don't know if this is the right way to make a hybrid app, but I got it working by serving assets over http with https://github.com/floatinghotpot/cordova-httpd .
On the local page bundled with the app I have added:
<script type="text/javascript">
document.addEventListener("deviceready", function () {
var httpd = cordova.plugins.CorHttpd;
httpd.startServer({
'www_root': '',
'port': 8080,
'localhost_only': false
}, function (url) {
// if server is up, it will return the url of http://<server ip>:port/
// the ip is the active network connection
// if no wifi or no cell, "127.0.0.1" will be returned.
document.getElementById('url').innerHTML = "server is started: <a href='" + url + "' target='_blank'>" + url + "</a>";
location.replace('http://192.168.0.134:9090/homechooser/beta/#' + JSON.stringify({'cordova.js': url + '/cordova.js'}));
}, function (error) {
document.getElementById('url').innerHTML = 'failed to start server: ' + error;
});
}, false);
</script>
<div id="url"></div>
Then on the remote webpage I have added:
(function () {
var hash;
if (location && location.hash)
try {
hash = JSON.parse(location.hash.substring(1));
} catch (e) {
}
if (hash && hash['cordova.js'])
$.getScript(hash['cordova.js'], function () {
alert("Running cordova.js");
});
})();
now to see if cordova can actually be used this way...
The cdvfile solution will not work for active content (js files) because of the mixed content policy. Here is how to make it work:
For android: Disable mixed content policy by putting the following code inside the pluginInitialize method of your cordova plugin:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
final WebSettings settings = ((WebView)this.webView.getView()).getSettings();
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
https://developer.android.com/reference/android/webkit/WebSettings.html#MIXED_CONTENT_ALWAYS_ALLOW)
Then include local cordova.js using:
<script src="cdvfile://localhost/assets/www/cordova.js"></script>
For ios: I submitted a PR to the file plugin which solves the mixed content problem on ios: apache/cordova-plugin-file#296 The fixed version is available at: https://github.com/guylando/cordova-plugin-file If you load a remote site https://example.com on the webview then it allows to access local files using the url: https://example.com/cdvfile/bundle/www/cordova.js instead of cdvfile://localhost/bundle/www/cordova.js And by this solves the mixed content problems
Include local cordova.js using:
<script src="/cdvfile/bundle/www/cordova.js"></script>
Thing is your are trying to load a web-url on the local hosted app, imagine doing the same thing on Native Android App, what would you do? you will place a web-client or a web-browser in your app. But Cordova/Phonegap already uses Web-Browser to render your pages. So its like a using web-browser inside a web browser.
You need to install InAppBrowser which will give you the ability to load 3rd party hosted web pages.
Sample Code
document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
//
function onDeviceReady() {
var ref = window.open('http://yourWebPage.com', '_blank', 'location=yes');
ref.addEventListener('loadstart', function(event) { alert('start: ' + event.url); });
ref.addEventListener('loadstop', function(event) { alert('stop: ' + event.url); });
ref.addEventListener('loaderror', function(event) { alert('error: ' + event.message); });
ref.addEventListener('exit', function(event) { alert(event.type); });
}
Related
I am using Cordova and InAppBrowser plugin to see external links in my app(android). But when device doesn't have connection and I am trying to go for external link it shows Android error(see image).
Question:
How to change this standard error page (standard error image) to my custom error page?
Thanks a lot
Use like this :
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
if(navigator.onLine) {
var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');
ref.show();
} else {
//create page in folder www like index2.html and include
alert("No Internet Pleas active your internet");
window.location = "index2.html";
}
}
I need to hit an API endpoint, which returns a pdf file (not a url to a pdf, but the actual data), then somehow display this pdf in my ionic application. Ideally, I'd like to just give it to some other application like the phone's mobile web browser but I'd be open to trying to embed it within my app as well. On iOS, I just use $window.open(url) and mobile safari knows to download and display the pdf that is returned. However, Android tries to download the file then tells me that it can't be opened when I try to open it.
I've also tried embedding it in the app with <embed> but nothing gets embedded. However, a similar method works with images in <img ng-src="url">.
I've also tried messing around with cordova FileOpener2 but am having a lot of trouble getting anything to work in that. If that's the right way to do this, I'd be open to re-visiting that method.
The closest I've gotten is definitely just sending it to the devices mobile browser as that works perfectly on iOS.
I solved it using filetransfer and fileopener2. My code is below. The main issues I ran into was not having <access origin="cdvfile://*" /> in my config.xml file and not having ngCordova installed correctly.
if (ionic.Platform.isIOS())
$window.open(APIUrl, '_blank', 'location=no');
else if (ionic.Platform.isAndroid()) {
var fileExtension = filename.substr(filename.lastIndexOf('.')+1);
//I have a dictionary with this somewhere else
var MIMEType = extToMime[fileExtension];
var uri = encodeURI(APIurl);
var fileURL = "cdvfile://localhost/persistent/file."+fileExtension;
$cordovaFileTransfer.download(uri, fileURL, {}, true)
.then(function(result) {
$cordovaFileOpener2.open(
fileURL,
MIMEType
).then(function() {
console.log("SUCCESS");
}, function(e) {
console.log("ERROR");
console.log(JSON.stringify(e));
});
}, function(e) {
console.log("Error: " + JSON.stringify(e));
});
}
I am trying to display image,docs from base64-string for Android and IOS. I am using inapp browser plugin to display image and doc files in app.
For IOS i am able to display images using below code.But facing issue with Android and Blackberry.
window.open(urlData, "_blank", "location=no,enableviewportscale=yes");
I am passing urlData parameter as base-64 string. Android and Blackberry nothing is displaying. After searching i found this post.
Alternative: just store that whole data string in your database. Then when you render your tag you can simply dump it into the src
attribute:>" />
After inserting above code i am able to display image but how to close the image ? How to open image in popup ? So user can close the image.
Thanks
First, window.open probably isn't working because all URLs have to be granted access specifically, for security. You can try to bypass it with this in your config.xml -- I don't know if it will work for data: URLs.
<access origin="*" subdomains="true"/>
<preference name="WebSecurity" value="disable"/>
If this doesn't work, how to show an image in a pop-up comes down to the design of your app. If you're using something like Ionic Framework, Bootstrap, jQueryUI, or Ratchet, they each have components for Modals or Dialogs you could potentially use. If you're not using a UI framework, you'll have to design your own pop-up div to contain the image tag, that is hidden again when you tap or dismiss it. Finding information on Google about how to do this is not very hard.
Good luck!
I am able to solve this issue in BlackBerry using below steps.
1)Remove webWorks.js from index.html
2)Replace below script inside index.html
<script src="worklight/cordova.js"></script> to <script src="../../cordova.js"></script>
3) Add below code inside js file. Need to pass urlData as Base64 string and filename.
requestFileSystem(LocalFileSystem.PERSISTENT, 7 * 1024 * 1024, function (fs) {
var ft = new FileTransfer(),
localPath = fs.root.toURL() + fileName;
ft.download(urlData, localPath, function (entry) {
entry.file(function (file) { console.log(file.size); });
window.open(localPath, "_blank", "location=yes,closebuttoncaption=Close,enableViewportScale=yes");
}, function (e) { console.log('download error'); console.log(e); });
});
I have created an application using Titanium Appcelerator in which I am using a webview to show some webpages. All the webpages to be displayed in the webview are HTML5 cache enabled, as I want the webpages to be available even when the application is running offline.
The problem which I am facing is that, the webview is not able to show the cached webpages when there is no network connection. But I have tested all the webpages in the browser, and all of them are working fine.
I am facing this problem for Android platform.
This is the code for the webview:
//FirstView Component Constructor
function FirstView() {
//create object instance, a parasitic subclass of Observable
var self = Ti.UI.createView();
var webview = Ti.UI.createWebView({
url: 'http://www.w3schools.com/html/tryhtml5_html_manifest.htm'
});
self.add(webview);
return self;
}
module.exports = FirstView;
The very url is working fine in the browser. How should I solve this?
you can use local html and it use jquery .ajax for load another webpage like that
//inside local page
<div id="pull"></div>
<script>
$.ajax({
url: "http://www.w3schools.com/html/tryhtml5_html_manifest.htm",
cache: true,type: "POST"}).done(function( html ) {
$("#pull").append(html);
});
</script>
I'm using PhoneGap (latest), Jquery 1.7. I'm having troubles getting some html loaded via AJAX into a div. My problem is simple, I have an index.html file in the www/ directory. And a js file that does this:
$.ajax({
type:"GET",
timeout:10000,
dataType: "html",
async: false,
cache: false,
url: "file:///android_asset/www/_liqui-cult.html",
success: function(data) {
$('#data_details .description').html(data); // never runs
},
error: function(xhr,msg){
alert(xhr.status + ", " + msg);
if(xhr.status == 0 || xhr.status == "0"){
alert(xhr.responseText); // always blank, if runs
}
}
});
Having spent the day Googling this error, I've tried numerous things, but the AJAX call never succeeds. I've tried changing the url to simply, _liqui-cult.html (without the file:// -based url). I've also tried /_liqui-cult.html.
I started out trying with the JQuery $.load, and that wasn't working, so I switched to the more verbose $.ajax call.
No matter what I do, I either get a 404 as the status, or, if I change the url to http://_liqui-cult.html, I get a status of 0, but nothing in the responseText.
So, I took JQuery out of the equation, and tried a simple XMLHttpRequest, as so:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && (xmlhttp.status==200 || xmlhttp.status==0))
{
$('#data_details .description').html(xmlhttp.responseText);
$.mobile.changePage('#screen_detail');
}
}
xmlhttp.open("GET","_liqui-cult.html", true);
xmlhttp.send(null);
Again, I've tried every conceivable url pattern to map to the html file. And still, the best I can get is xmlhttp.responseText is blank.
So how about cross-origin issues? Here is what I've tried:
<access origin=".*"/>
<access origin="file://*"/>
<access origin="*"/>
Again, I've tried all ways of mapping to the html file, with those different access origin settings, and I still cannot load the html file.
Any ideas?
Changing the name of the html file that gets AJAX-loaded from "_liqui-cult.html" to the same name without the underscore "liqui-cult.html" fixed the problem.
Seems something else is wrong in your project. The following gist have some of the files from my test application and it works without any issue in Android.
https://gist.github.com/2873186