I have a very simple HTML5 app written with trigger.io that fails running under Android 4.4 with errors stating that local content cannot be accessed. Example:
E/AndroidProtocolHandler( 2236): Unable to open content URL: content:////io.trigger.forge9aee7db8338b11e4b77d1231392b77b0/src/images/connect4.jpg
The same code works find under Android 4.3. This applies to all local content including images, CSS and JavaScript. All resources are referenced with relative paths such as "images/image.jpg".
My best guess is that there is an access policy change in newer versions of Android OS but I cannot figure out the details. I have made sure that nowhere in the code attempts to access external resources.
Antoine van Gelder was incredibly helpful on this. His diagnosis was absolutely correct that jQuery Mobile is rewriting the URLs for resources which causes newer versions of Android's Chrome Webview to fail when accessing resources. The generated URLs contain quadruple slashes after the protocol like this:
content:////io.trigger.forge9aee7db8338b11e4b77d1231392b77b0/src/resource.png
The extra slashes cause Webview to fail. Possibly some excessive checking for correctness or a security implication?
Antoine's suggestions of using older versions of jQuery Mobile or building a custom jQuery Mobile without Base Tag will probably work in some circumstances though neither was quite sufficient in my case. Particularly, removing Base Tag also removes some other functionality I needed.
An alternative approach is to make a minor hack to jQuery Mobile. For version 1.4.3 I did the following:
Edited an un-minified version of jQuery Mobile's javascript
Modified the getLocation function:
Save the return value to a temporary variable
Modify the temporary variable by removing quadruple slashes.
I used something very specific and restricted to the "content" protocol: "retVal = retVal.replace("content:////","content://");"
Return the fixed temporary variable
It looks like, starting with v1.3, jQuery Mobile are rewriting the URL's in your document which breaks the Chrome Webview's access to files in the app sandbox.
You could try filing a bug report with the jQuery Mobile devs but to sort this out in the short term your best options are probably one of:
1) Fall back to jQuery Mobile 1.2.1
2) Build a custom version of jQuery Mobile which excludes some navigation features. (Go to download builder (http://jquerymobile.com/download-builder/), scroll down to "Navigation" and de-select the "Base Tag" module)
This should be fixed in JqueryMobile 1.4.4.
Related
The Phonegap documentation indicates that it is possible to get the app's browser wrapper to load a custom error URL instead of showing a generic message should the application encounter an error. I find myself asking two questions here:
From what I can tell this is an Android-only feature. So is there an equivalent method for iOS? The Phonegap iOS documentation does not say anything on the subject.
Secondly, can the error URL point to a separate HTML document in the project/www folder from which the application will be built or does it have to be an external URL. My thinking is that an external URL does not in fact make much sense - what if the application error happens when the user is not on a network?
I'd be most obliged to anyone who might be able to calriify these issues.
From OP
From what I can tell this is an Android-only feature. So is there an equivalent method for iOS? The Phonegap iOS documentation does not say anything on the subject.
There appears to be no equivalent for iOS in the documentation. You can safely assume, if it is not there, it is not available.
To be clear, the underlying iOS library has no default error method. On Android, there is a method for dealing with this.
Secondly, can the error URL point to a separate HTML document in the project/www folder from which the application will be built or does it have to be an external URL. My thinking is that an external URL does not in fact make much sense - what if the application error happens when the user is not on a network?
Your assumption is correct. The "error.html" should be on the device and in the www/ directory. The file should NOT be on the network/internet. You'd be surprised how many times I see this error.
I developed a simple Firefox extension that fully works on Firefox for desktop computers. The extension uses a few SDK elements which are incompatible with Firefox for Android, likePanel, making it incompatible on Android.
I created two separate versions of the extension - one for desktop computers, and another one without the incompatible SDK elements which is compatible with Android. Everything works, however when I came to submit both extensions to the Mozilla AMO they were rejected and I was asked to consolidate them into a single extension.
How can I create a Firefox extension which uses desktop-only SDK elements on desktop Firefox and does not use them on Firefox for Android?
I ended up researching the issue and decided to write a blog post about the solution: http://blog.danielmittelman.com/2014/12/developing-firefox-add-ons-with-desktop-and-android-compatibility/
Here's the gist of it: There are SDK elements like panel or ui which are explicitly incompatible with Android. Ensuring compatibility with Android requires 3 steps:
1) Using only necessary Android-incompatible SDK elements (what you don't need - don't use)
2) Identifying the platform and using conditional statements to enable or disable potentially incompatible code
3) Creating and/or running the add-on using the --force-mobile flag of cfx
Given that you already have completely different versions for desktop and Android, you should be able to use the use the [flags] in your chrome.manifest to provide a different directory for the content, or other type of entry, based on the application ID using the application=app-ID flag. The application ID is different for Firefox for Android and Desktop Firefox.
The flags are explicitly there for you to be able to have different content based on the application (e.g. desktop/Android), the version of the application, the OS, the OS version, etc.
Example chrome.manifest entries would be:
content myAddon chrome/content-desktop/ application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
content myAddon chrome/content-android/ application={aa3c5121-dab2-40e2-81ca-7ea25febc110}
In the above example the URLs referencing chrome://myAddon/content would come from the chrome/content-desktop/ directory for desktop Firefox and the chrome/content-android/ for Firefox on Android.
If you have content that is shared between applications, you could have an entry like:
content myAddonShared chrome/content-shared/
Because you are using the Add-on SDK, you may have a bit more trouble doing this. I suspect that there is no way to set cfx up to provide such entries, and that you will have to make them manually.
(re-post from the PG google group)
I know there's been a lot of conversation on this in the past, but I've been researching it for the past few days and couldn't seem to find a definitive answer (or even what it would entail).
I was wondering how plausible it would be to embed a snapshot build of the Chrome webview (or even the Gecko webview) into a Phonegap app and to use that in place of the native webview that PhoneGap uses. The problem is twofold - 1) Android's native browser/webview is terrible and 2) Each phone seems to have idiosyncratic bugs/differences, which having one set snapshot to build against would fix.
I've seen answers ranging from "Oh, yeah, just build the source and drop it in" to "You'd need a full team of Java devs to hack the PhoneGap API core to get it to work". Does anyone have an answer of what it would entail, how much time it would take, if it's even plausible, etc? I suppose the biggest concern is - given we can get a snapshot build of the Chrome webview, does that break any of the connections to the PhoneGap APIs? Are they tied specifically to the native webview?
Any and all thoughts are appreciated. Thanks!
Chrome has the ability to be embedded by use of the Content Module. In theory (I have never done it) you can build this and embed it into your Application and use that instead of a WebView - it has the advantage of being an up to date Chrome and multi-process. It loses value in that it can't be used pre-Jellybean.
We will develop a hybrid app, using localstorage as http cache , and it will shared with multiple webview.
so are there any known localstorage compatibility issues ?
android 2.1 ~ 4.x (most for 2.3 ~ 4.x)
First of all I don't think that the local storage could be a suitable solution for caching, because it's funcionality only includes the possibility to save/retrieve/delete key/value pairs, but I don't know exactly what your purposes are.
About the compatibility I would say that the local storage of the android's WebView does not function very well, because it is not persistent across the different tabs/windows, so actually it becomes useless in my opinion. If you want to share the same data in multiple webviews the only way is to use a java database and a javascript interface. There is a implementation on github, which should be suitable for that.
I render a local web page in Android and include locally referenced webfonts in woff, ttf and svg format (not fetched via HTTP). However, these are not rendered at all on two different devices (API 2.2 and 2.3) and the console log keeps empty. Of course the fonts work just as they should on any webfonts-capable browser and even old WebKit versions that are older (529.x) than the WebKit version used on Android (533.1). Any clues what piece I am missing in the puzzle?
Ok, seems as if this is a long-standing Android bug, where the Webview pokes on a local() source reference and discards the other sources. This gives you a more detailed response how to define your fonts cross-platform, so that they even work on IE.