I know this question has been asked before, but I've tried all the proposed solutions and nothing seems to work!
I'm working on a mobile app built with Phonegap (+Angular but I don't think that's important). In this app I'm using the geolocation plugin. More specifically my config.xml looks like the following:
<?xml version="1.0" encoding="UTF-8" ?>
<widget xmlns = "http://www.w3.org/ns/widgets"
xmlns:gap = "http://phonegap.com/ns/1.0"
id = "......"
version = "1.0.0" >
<name>.....</name>
<preference name="permissions" value="none"/>
<preference name="orientation" value="default" />
<preference name="target-device" value="universal" />
<preference name="phonegap-version" value="3.6.3" />
<gap:plugin name="org.apache.cordova.geolocation" />
<gap:plugin name="com.phonegap.plugins.PushPlugin" version="2.4.0" />
<gap:plugin name="org.apache.cordova.network-information" />
<gap:plugin name="org.apache.cordova.statusbar" />
<gap:plugin name="org.apache.cordova.device" />
<gap:plugin name="org.transistorsoft.cordova.background-geolocation"/>
</widget>
There are times that I want to get the current position of the user, so I'm doing it as follows:
navigator.geolocation.getCurrentPosition(function (position) {
.....
}, function (error) {}, {
enableHighAccuracy: true,
maximumAge: 30000,
timeout: 10000
});
This is working fine on iOS devices and it even works on the ripple emulator for Android.
But when I try to run the app on Android and more specifically on Nexus 4 and 5, the geolocation doesn't seem to work. It's not that it's giving me an error, it's just trying to retrieve the position without any luck.
However, all the other apps that are using geolocation and also the geolocation in the browser is working perfectly fine!
I would also like to note that I'm using Phonegap Build to build the app.
Does anyone know how I can fix this problem? Did anyone have the same issue?
From your code sample, how would you know that there's no error being raised when you have an empty error handler function (error) {}?
getCurrentPosition() makes a single request for the device position. If this is called just once, the position timeout may occur before the GPS hardware on the device has had a chance to get a position fix.
I'd suggest using watchPosition() instead to setup a watcher which will call the success function each time the OS receives a location update. If you only need a single position, you can clear the watcher, optionally checking to make sure you've got a position of acceptable accuracy.
For example:
var minAccuracyInMetres = 50;
var positionWatcher;
function onDeviceReady(){
positionWatcher = navigator.geolocation.watchPosition(
geolocationSuccess,
geolocationError,
{maximumAge:0, timeout: 10000, enableHighAccuracy: true});
}
function geolocationSuccess(position){
// Reject if accuracy is not sufficient
if(position.coords.accuracy > minAccuracyInMetres){
return;
}
// Only single position required so clear watcher
navigator.geolocation.clearWatch(positionWatcher);
// Do something with the user's location...
}
function geolocationError(error){
console.warn("Error while retrieving current position. " +
"Error code: " + error.code + ",Message: " + error.message);
}
document.addEventListener("deviceready", onDeviceReady, false);
Related
I've used a plugin to try and lock the screen orientation within my PhoneGap app:
cordova-plugin-screen-orientation
Within my app page I have the following code extract:
// Once DOM is loaded...
$(document).on('pagecreate', function() {
window.screen.lockOrientation('portrait'); // Seems to set variable but not LOCK screen?
var orient = screen.orientation; // Works
alert(orient); // Works
window.addEventListener("orientationchange", function(){ // Works
alert(screen.orientation); // e.g. portrait // Works
});
... Other code etc.
As you can see from the comments the plugin seems to be installed correctly as I am successfully calling portrait-primary, landscape-secondary etc. as I rotate my phone. The issue seems to be the function isn't LOCKING the screen?
Any help would be GREATLY appreciated!
Try setting this attribute in your config.xml.
<preference name="Orientation" value="portrait" />
I've been struggling with this for days now. I have an Ionic 1.3.0 application using ngCordova#0.1.26-alpha
I am using $cordovaFile.writeFile() to store images in cordova.file.applicationStorageDirectory. I've tried every storage location with the same result. The file is good, I can view it in a file manager app. I would like to use the file as an ng-src for an <img>. On Android, this might look something like: cdvfile://localhost/sdcard/Android/data/com.example.mobile/img-49444.jpg
So in my page, I bind the URL to the <img> and stick a sanity check <pre> in there to see that record.image_url has a valid URL:
<img ng-src="{{record.image_url}}">
<pre>{{record.image_url}}</pre>
While the URL looks good to me, the image simply doesn't render and it seems no amount of effort will convince it. I've tried file:///, cdvfile://, and http:// URLs, using entry.toURL(), entry.toInternalURL(), etc., from the response objects from $cordovaFile.writeFile(). All approaches fail with either a broken image icon or an empty <img> element rendering.
I've tried adding this CSP tag to index.html (and dozens of other attempts)
<meta http-equiv="Content-Security-Policy" content="img-src 'self' data: blob: filesystem: cdvfile://*;">
And I've tried messing around with $compileProvider, like:
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|cdvfile):|data:image\//);
And throwing everything I can at config.xml Cordova whitelists
<plugin name="cordova-plugin-whitelist" spec="~1.2.1">
<access origin="*"/>
<access origin="cdvfile://*"/>
<access origin="file://*"/>
<access origin="file:///*"/>
<allow-intent href="cdvfile://*"/>
<allow-intent href="file://*"/>
<allow-intent href="file:///*"/>
<allow-navigation href="cdvfile://*"/>
<allow-navigation href="file://*"/>
<allow-navigation href="file:///*"/>
</plugin>
Nothing works. I don't think this is a white list plugin issue - my assumption is that when the image is rejected due to the white list, the image is displayed as a broken link, whereas the <img> element is instead empty and takes up no space when the white list is not rejecting it. This behavior is consistent on Android 4.4.4 and 6.0.1.
Any help would be greatly appreciated.
So as to not mislead others that come across this answer, I managed to get cdvfile:// URLs to work even in livereload mode without issue in a new app. Simply:
config.xml
<access origin="*"/>
<access origin="tel:*" launch-external="yes"/>
<access origin="geo:*" launch-external="yes"/>
<access origin="mailto:*" launch-external="yes"/>
<access origin="sms:*" launch-external="yes"/>
<access origin="market:*" launch-external="yes"/>
<access origin="cdvfile:*"/>
<plugin name="cordova-plugin-whitelist" spec="~1.2.2"/>
Note that <access> rules are NOT supposed to be nested under <plugin>. The documentation doesn't explicitly call that out.
app.js
.config(function ($stateProvider, $urlRouterProvider, $compileProvider) {
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|file|blob|cdvfile|content|tel|geo|mailto|sms|market):|data:image\//);
I do not have a Content-Security-Policy meta tag declared in index.html
And all is well.
So it turns out I can use file:///* paths for ng-src if I deploy the built .apk to the device instead of using the Ionic livereload server (ionic run android -cls). It should be obvious that hardware-level functions won't work through something like the browser-based ionic serve, but it was less obvious that testing on actual hardware would fail like this based on the livereload server. I incorrectly assumed that the livereload server was just a file monitoring approach where it would stream assets onto the device as they change and maybe notify the app to reload. Instead it seems they are just hosting a web server directly on your host. $cordovaFile correctly reads/write files on the device even in livereload, but the web views in the app don't have native access to the files on the device in that mode. I could read the file contents with $cordovaFile.readAsText() and that would still work even on livereload, but when it comes to the web views in the app reaching files, well, it just doesn't have any access to native device URLs.
If anyone else runs into this issue, here's how I'm writing the file and capturing the URL so that it works in a view.
$ionicPlatform.ready(function () {
var targetDir = cordova.file.externalApplicationStorageDirectory + "files/";
$cordovaFile.writeFile(targetDir, name, imageData, true)
.then(function (info) {
console.log("File created", info.target.localURL, JSON.stringify(info));
$cordovaFile.checkFile(targetDir, name).then(function (entry) {
console.log("Got file entry", entry.toURL());
q.resolve(entry.toURL());
});
}, function (e) {
q.reject(e);
});
});
return q.promise;
}
On android this would return a URL like:
file:///storage/emulated/0/Android/data/com.example/files/<name>
I've found that cordova-plugin-whitelist can be empty in config.xml - we don't need any whitelist directives for file:///. Also, no $compileProvider.imgSrcSanitizationWhitelist() changes are necessary - the default whitelist should work.
I never did get cdvfile:// URLs to work, regardless of whitelist settings, Content-Security-Policy directives, or app.config tweaks.
I am developing an hybrid application for android and iOS. This is not my first app, but I don't consider myself an expert either. At the moment I'm targeting Android 4.4 or later. For iOS I got an iPhone 4S to test, not supporting anything below iOS 9.2. To make this app I'm currently using Phonegap Build, which outputs version=cli-5.2.0 and using jQuery Mobile 1.4.5 as the framework to handle the UI, navigation and so on. The Javascript is being loaded locally - from the device.
Considering some server interaction takes some time to load, I was thinking to show a loading gif while the server interaction processes. For this matter I'm using a loader widget from jQuery Mobile. The code for the ajax request calls has the following code:
$.serviceCall = function(web_method, web_root, params){
var ajax_response;
var request_url = 'http:/some.url.com/' + web_root + '/' + web_method;
$.mobile.loading( "show", {
text: "loading",
textVisible: false,
theme: "z",
html: ""
});
$.ajax({
type: 'get',
contentType: 'application/json; charset=utf-8',
async: false,
dataType: 'json',
url: request_url,
data: params,
}).done(function(data){
ajax_response = data
ajax_response.callback = 'done';
$.mobile.loading("hide");
}).fail(function(jqXHR, textStatus, errorThrown){
var failure_details = {
status: jqXHR.status,
text_status: textStatus,
error_thrown: errorThrown
};
ajax_response = failure_details;
ajax_response.callback = 'fail';
$.mobile.loading("hide");
});
return ajax_response;
};
Which works perfectly fine when accessing from a desktop browser or from ripple emulator to simulate the actual device.Once the request starts, the loader shows, hides as soon as the request ends and makes the page transition.
However, on android doesn't work. Whenever the request starts the loader doesn't show up no matter how long the request takes. Is there any trick for mobile OS that I need to apply in order to make it work?
check this guide on how to inspect the App.
I suggest taking out $.mobile.loading("hide"); so you can keep the loader running to see whats happening. might be a z-index issue or an error in the console
You have made a common mistake. You need to apply the whitelist system. It is required as of Cordova Tools 5.0.0 (April 21, 2015). For Phonegap Build, that means since cli-5.1.1 (16 Jun 2015)
Add this to your config.xml
<plugin name="cordova-plugin-whitelist" source="npm" spec="1.1.0" />
<allow-navigation href="*" />
<allow-intent href="*" />
<access origin="*" /> <!-- Required for iOS9 -->
NOTE YOUR APP IS NOW INSECURE. IT IS UP TO YOU TO SECURE YOUR APP.
Add the following to your index.html
<meta http-equiv="Content-Security-Policy"
content="default-src *;
style-src * 'self' 'unsafe-inline' 'unsafe-eval';
script-src * 'self' 'unsafe-inline' 'unsafe-eval';">
This whitelist worksheet should help.
HOW TO apply the Cordova/Phonegap the whitelist system
If it is not this, then there may be a JQuery Mobile setting which I may not be familiar with.
I hope you'll can help me to find an issue to my problem.
I'm developping an application who should use WhatsApp. This application is using HTML5, CSS3 and Javascript. I am using this link to send an message with WhatsApp :
<a href="whatsapp://send?text=Test 1">
This link work perfectly when you use directly a browser but when I use PhoneGap I have a error like this :
net::ERR_UNKNOWN_URL_SCHEME
I have tested some issues but doesn't work. I have also checked the Documentation but nothing...
Can you help me please ?
Thanks
EDIT
Here is the solution to my problem (thanks to #jcesarmobile):
<access origin="whatsapp:*" launch-external="yes" />
Many thanks :)
Edit for newer cordova versions:
Use <allow-intent href="whatsapp:*" />
Old answer:
Add this line to your config.xml
<access origin="whatsapp:*" launch-external="yes" />
Or use the social sharing plugin
https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin
<button onclick="window.plugins.socialsharing.shareViaWhatsApp('Message via WhatsApp', null /* img */, null /* url */, function() {console.log('share ok')}, function(errormsg){alert(errormsg)})">msg via WhatsApp (with errcallback)</button>
First and more important, add this line to your config.xml
<allow-intent href="whatsapp:*" />
after use the code:
Hello, world!
window.location.href = 'whatsapp://send?text=hello world';
this worked for phonegap IOS
window.open("'whatsapp://send?text=hello world'", "_system");
for android.
I have a problem with phonegap and $.get (jQuery). It's actually only a webapp which exists already but I want to bring it on my Android Smartphone.
So my $.get is working and I have this settings:
In res/xml/config.xml:
<access origin="*"/>
In AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
But it's not working :(
Edit 1 (17.11.2013 15:23):
alert("getData: "+searchTerm+" in "+language);
$.get("http://mysite.de/search.php", {art: searchTerm, lang: language}).done(function(data){
alert("daten: "+data);
}, "html");
alert("ready");
Only the first and the third alert is working.
The problem is
XMLHttpRequest cannot load http://mysite.de/search.php. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
You need to allow access to http://mysite.de/search.php from any domain
Allow it by adding code to your php page:
header("Access-Control-Allow-Origin: *");