There are a couple of similar SO questions here about Cordova paths, and that they should always be relative due to the Android and iOS platforms. But my web app takes advantage of the browser's address bar by altering the current path for bookmarking purposes.
For example, you might be on the books page
mywebsite.com/books
and then click a book, leading you to
mywebsite.com/books/some-book
but the page itself never changed as it is an SPA. However if I used relative paths everywhere, then refreshing on mywebsite.com/books/some-book would now try and load assets relative to /some-book such as app.min.js, etc.
So this relative path system fails both on the browser and on a mobile built cordova app for Android and iOS.
For browser I can maintain the absolute paths I have like /js/app.min.js but I was hoping for some solution for Android/iOS/Cordova to use fixed paths as well. When I try /js/app.min.js it looks for files in files:///js/app.min.js which fails.
I have the power of manipulating the output of my builds quite easily, so if there were some magic path I could inject after my builds for iOS/Android or Cordova in general, such as file:// or whatever other magic paths there are, then I can solve this problem.
So does absolute pathing exist when building a web app into a mobile app with Cordova?
Try setting your paths with
<... src="assets/www/js/some.js">
Related
Executive summary: can't display a pdf file on Android Firefox.
I created an HTML page on my laptop and displayed it using Firefox. The page is a simple menu, consisting solely of links to my wife's sewing machine manuals, like so (skipping over header, title, and stuff, no css, not xhtml):
<p><ul>
<p>
<p><li><a href="file:///storage/3C5D-4F8A/Manual/thing.txt">
<strong>Thing
</strong></a></li>
</p>
<p><li><a href="file:///storage/3C5D-4F8A/Manual/overlockbasics.pdf">
<strong>Overlocking Basics
</strong></a></li></p>
<p><li><a href="file:///storage/3C5D-4F8A/Manual/allaboutthread.pdf">
<strong>All About Thread
</strong></a></li></p>
</p>
...and so on. The goal is to have the manuals handy to the sewing machine. The phone is handy.
On a laptop, clicking the link pops up the associated pdf file, which is expected behavior. However, when I put the HTML file on her phone (and after adjusting the file paths), clicking a link returns a 'unable to download file' message.
To insure I had the correct path at least, I put that 'thing.txt' link in; clicking that returns the contents of the thing.txt file ("This is a thing", if you were wondering), so the path as specified seems correct, and that at least the text display 'plugin' works.
Tried attaching a 'type="application/pdf"' to each anchor tag, but that had no effect. From what I've discovered, Firefox is supposed to have a built-in PDF viewer - a sensible notion - although I have a suspicion that it only works with downloaded files...but if that's true, why does it work on the Win10 laptop? Inquiring minds want to know. True, there are some differences between the two platforms, so perhaps that's just the way things are.
To reiterate, the files I'm trying to display are right there on the phone's storage card.
The phone is a Galaxy S5 sport (android version 6.0.1); Firefox version is 68.3.0.
The laptop is Win10, Firefox version is 71.0.
I see that other people have had problems sort of like this, but their issues appear more complex. This does not seem to be complicated, aside from the common not-working part.
If someone can suggest a solution that doesn't involve third-party add-ons, or reconfiguring Android, or dragging Google into the process, (or as someone suggested elsewhere, writing one's own browser), it's appreciated. Prefer someone pointing out what I'm doing wrong. It's entirely possible that something so simple cannot be simply done.
To see what happens on a Raspberry Pi (mainly because it was handy), I mounted the Samsung as a mts device, modified each anchor tag's path to a single dot/slash preceding the PDF file name, and ran the HTML file into both Firefox ESR, and then Chromium. Oddly, both browsers spontaneously opened and populated tiny PDF windows corresponding to each href; no link click was required. So all that demonstrated is that Firefox behaves differently depending on the platform; I'm glad you were all sitting down for that revelation. Still, it was interesting, in that those browsers had no trouble displaying something. Note I'm not complaining about that; it was just an experiment.
To recap - main interest: Firefox on the Android not displaying PDF when anchor tag clicked.
Thanks.
I've build an application that uses Tesseract (V3.03 rc1) to identify some specific text strings. These are, unfortunately, printed on a custom font that requires that I build my own traineddata file. I've built the application on both iOS (using https://github.com/gali8/Tesseract-OCR-iOS for inspiration) and Android (using https://github.com/rmtheis/tess-two/ for inspiration as well).
The workflow for both platforms is as follows:
I select a bounding box on the preview screen for where I can crop out the relevant text, and crop the image accordingly.
I use OpenCV to get a binary image (using OpenCV's adaptive threshold function with the same parameters for both platforms)
I pass this binary image to Tesseract. Both platforms (Android and iOS) use the same traineddata file.
And yet, iOS recognizes the text strings perfectly, while Android keeps misidentifying certain characters (6s for Ss, As for Hs).
On both platforms, I use the same white list string, I disable load_type_dawg and load_system_dawg, and also choose to save the blob choices.
Has anyone encountered this kind of situation before? Am I missing a setting on Android that's automatically handled in iOS? Is there something particular about Android that hasn't crossed my mind?
Any thoughts or advice would be greatly appreciated!
So, after a lot of work, I found out what was wrong with my Android application (thankfully, it wasn't an issue with Tesseract at all). As I'm more familiar with iOS apps than Android, I wasn't sure how I could load the traineddata file onto the application without requiring the user to have the file loaded on their external storage device. I found inspiration in this project (http://www.codeproject.com/Tips/840623/Android-Character-Recognition), as they autoload the trained data file.
However, I misunderstood how it worked. I originally thought that the TessDataManager did a file lookup on the project's local tesseract/tessdata folder in order to get the trained data file (as I do this also on iOS). However, that's not what it does. It, rather, checks the internal file structure (data/data/projectname/files/tesseract/tessdata/traineddatafilegoeshere) to see if the file exists and if it doesn't, it copies over the trained data file it keeps in the Resources/Raw directory. In my case, it defaulted to the eng file, so it never read my custom font file.
Hopefully this helps someone else having similar issues. Thanks to Robin and RmTheis for all of your help!
I am developing android phonegap application. which has around 65 images (~10kb size for each). My application is working as expected on Ripple chrome plugin as well as on Chrome and FF browser. but when I load it on emulator some images are not able to load.
I have attached screenshot for the reference.
I tried using the jQuery preload plugin but no luck.
Can anyone help me please! Thanks
EDIT:
I have tried the same code without any change on iPhone and WindowsPhone7, Images are showing up fine on both the platform.
Try creating an identical copy of the image (../image_copy1.png, for example), and swap that code out in lieu of the image location that isn't working.
Sometimes emulator programs freak out with file paths either due to localized caching of data or actual logistical errors in the emulator program itself. Dreamweaver has similar problems, as do a host of other dev/testing suites - local caching of images is not an uncommon problem. You can circumvent this issue sometimes by uploading a copy of the desired file (but not copying it within the program itself) - causing a fresh, noncached upload of it. This is by no means a "proper" solution, but it's a quick and dirty workaround for a buggy emu/dev program.
If you are loading the images from an external source, you may need to 'whitelist' the source. Did you add the domain name into the Cordova config file? It is under res/xml/config.xml
<access origin="www.example.com" />
I know that it is necessary for cross domain AJAX requests but not sure for images, you could give it a try.
Can't help much.
Emulator acts cranky some times.
I have faced the issue multiple times.
At the best, you can try creating another avd-image... but at least I cannot guaranttee that it will work.
I have what I think is a fairly standard set-up of an existing web-app and would like advice on how best to adapt it for creating native versions via PhoneGap, in a way that we can keep developing the web-app and updating the phonegap generated versions from it with minimal rework.
I am a PhoneGap novice. I have searched around and tried various suggestions from StackOverflow etc with no luck, at least for my set-up.
The app is developed in GWT and consists of:
static resources in a shared folder for all of the app
/static/ with images, fonts, css.
The css define some font-families, referencing font files in /fonts
We refer to these static resources from html files and JavaScript code using absolute
paths.
static resources in a number of sub-folders (by GWT modules FYI)
Such as /LoginGadget, which will have GWT generated html, Javascript and sometimes subfolders with css and css-images.
GWT-RPCs
These are basically servlets where GWT takes care of serialization etc, and are accessed from our client code via XHRs under the covers
PhoneGap Build
I have started looking at creating a packaged app using PhoneGap and run into some problems where I need advice (Android example).
I have created /assets/www and put an index.html file in there and got it going.
I copied a version of our /static/ folder and our /LoginGadget folder under that "root" to see, and started it using
super.loadUrl("file:///android_asset/www/index.html");
which works.
In all our GWT generated html and Javascript files we have references to static resources using both absolute (e.g. "/static/....") and relative paths (e.g. from a LoginGadget Javascript, it might reference "css/some.css").
The relative paths work, as they reside "under" the folder where the html/js that references them lie.
Problem 1
However, references to absolute paths fail, despite PhoneGap starting by saying:
DroidGap: url=file:///android_asset/www/index.html baseUrl=file:///android_asset/www/
I expected a reference to "/static/images/file.png" from say index.html to be appended to the "baseUrl" to give file:///android_asset/www/static/images/file.png and hence work, as that is where the file lies.
I have had to modify index.html to use "static/image/file.png" for it to work.
But I'd have to recompile all our GWT app with a different configuration to modify all references to resources, and references from other files in sub-folders back to "/static/" won't work if modified to be just "static/".
How can I get absolute path references to "map" to /assets/www or similar?
(See below, I've looked at using the "base" tag....)
Problem 2
The GWT RPCs make the XHR request to the server the html/js was served from.
This works great as the app doesn't have the host server name hard-coded, and is in fact deployed on many different appengine appids/domains for testing etc.
Here the html/js files are "served" from file:/// hence I need to specify the server somehow.
I tried specifying with the "base" tag as documented, but then any reference I have in my html/js to a resource that doesn't specify "file://" seems to be made to the server specified in "base"..... hence I am not loading my local resources anymore and I basically have a web-app served from my server.
Want
What I'd like to do, is to be able to take the (pretty large) compiled and tested app from my wab-app's war (/static and all my /GWT-Module folders) untouched and copy them into /assets/www on my PhoneGap app and then add some boiler plate or start-up code and run as is.
Sounds like a big request, but I think if I could properly specify two things:
file path to use as "root" for absolute paths for resource requests that don't specify a http/https protocol (or other protocols.....which I already see are handled in DroidGap.java)
server (protocol, hostname, port) to use for any XHR requests
Then everything would come out in the wash!
I thought this would be a faily "standard" setup and already covered. Maybe it is and I'm just missing something.
Comments? suggestions?
Thanks in advance for any help.
Do you know about mgwt? http://www.m-gwt.com
Its a mobile framework for GWT built by one of the GWT Steering Committee members and it has phonegap integration for GWT apps as well.
There is a lot of docs in the projects and a very friendly user group.
Let me address your problems with a little more detail:
Problem1:
If you are using absolute path you will get that inconsistent behavior with phonegap, since the browser builds those urls locally and a reference to / means the root entry on the phone.
Using absolute URLs is a bad idea most of the times and I would recommend you to change that in your app (as you already did).
Problem2:
To use GWT RPC with phonegap read this blog post that I made to address the issues: http://blog.daniel-kurka.de/2012/04/gwt-rpc-with-phonegap-revisited.html
We solved these problems with two separate actions:
1) I wrote an ant target that as part of our build takes the web-app, and replaces the paths in all internal url references it finds, making them fit what's needed for them to work within the app. It still seems a major bug in phonegap to me. Maybe it's been fixed in newer versions?
2) We subclassed the RPC service class and modified it to have a static member that is the service endpoint. At the start-up of our phonegap app we modify the end-point to point to the desired server and presto.... all our GWT RPCs point to the right place.
I'm porting a rather large game engine written in C++ from Windows/Mac to Android. There is a lot of pre-existing code to read assets for games. In addition, there is quite a bit of code doing file system calls (stat'ing the files to make sure they exist, looking up all of the files and directories inside of a directory, etc.)
Right now, I'm focusing on just getting something up and running as quickly as possible, so I'd prefer not to have to rewrite a lot of this. What would be a good way of getting our game assets onto the device and accessing them with minimal changes to our existing standard C++ file system API usage?
I've got some basic support implemented already using the Asset Manager API, but that doesn't support the file system calls and I'm concerned that the 1 MB asset size limit is going to bite me at some point.
I've also looked at OBB, but the tools for creating an OBB file don't look like they are part of the current SDK/NDK. Otherwise, that looks like it would be perfect.
Is it a horrible idea to package up all of the files and just extract them on the SD Card the first time the app is run? Or is there some better way of dealing with this?
Update: I'm also not very concerned on being able to run on a broad range of devices, I am specifically looking at newish tablets, probably the 10.1" Samsung Galaxy tab.
We ran into a similar problem in developing our (data-file-heavy) app, and we ended up deciding to keep the APK tiny and simply download our data files on first run; they're going to have to be downloaded either way, but a small APK works much better on older devices without a lot of internal storage. Plus, you can potentially rig up a way for people to copy over the files directly from their computer if they have a limited data plan or a slow internet connection on their phone.
The "Downloader" sample app in apps-for-android (confusingly buried under "Samples") is almost a fully-implemented solution for this - you can pretty much just plug in the particulars of your data files and let it do the rest.
I wrote an app that relies on putting a good amount of native code into the Android filesystem. I did this by packaging the files into the APK as 'resources'. Instead of pushing them to the SD card, you can put then into the application's private namespace, I.E. /data/data/com.yourdomain.yourapp/nativeFolder.
For details on how to accomplish this, you can see my answer to this question.
It's fairly simple to package to just unpack them on the first run and never worry about them again. Also, since they're under the application's namespace, they should be deleted if/when someone were to decide to delete your app.
EDIT:
This method can be used to put anything into the app's private area; /data/data/com.yourdomain.yourapp/
However, as far as I know, your application has to be the one to create all the folders and sub-folders in this area. Luckily this is fairly easy to do. For example to have your app make a folder:
Process mkdir = Runtime.getRuntime().exec("mkdir " +localPath);
That works as it would in most linux shells. I walked through the assets folder I packaged into my APK, made the corresponding directories and copied all the native files to those directories.
What you might be more concerned with is the limited Android shell. There are many commands that you might want that aren't present. stat for example isn't available, so all of this may be moot if your native code can't make it's system calls.