Goal
I'm working on a cordova application that target tablets with android 9. One of the main features of the application is to retrieve the current longitude and latitude of the tablet without having to be connected to the internet or requiring a sim card.
Behavior
I'm using the cordova plugin add cordova-plugin-geolocation
to add the cordova-plugin-geolocation
plugin, which only seems to be working when the the tablet is connected to the internet.
If the wifi is turned off then I just get an infinite waiting time.
If I set a timeout, then the error function is called after the timeout finishes.
Checks
- I've confirmed that the device I'm using has a functioning gps system since other GIS applications are functioning properly without the use of wifi/data
- The application is allowed to read my location
- I've tried using a couple of different timeouts (10E3 - 5*60E3 ms) at a couple of different locations without success
JavaScript + HTML
The first script in my html is <script src="cordova.js"></script>
, none of the scripts have the async tag so all of them run after the cordova script is loaded (still use document.addEventListener("deviceready", ..., false);
when applicable)
There are no errors on the console or the network tab.
Below is the function that I use to get the geolocation and it always prints no data
when the wifi is turned off.
var deviceIsReady;
document.addEventListener("deviceready", function() {
deviceIsReady = true;
}, false);
function getLocation() {
return new Promise(function(resolve, reject) {
if (!navigator.geolocation || !deviceIsReady) {
console.log("Can't use geolocation");
return reject();
}
var unreliablePosition;
navigator.geolocation.getCurrentPosition(function(position) {
unreliablePosition = position;
}, function(err) {
console.log("Failed to get unreliable geolocation");
}, {
enableHighAccuracy: false,
maximumAge: Infinity,
timeout: 4.5 * 60E3
});
navigator.geolocation.getCurrentPosition(function(position) {
resolve(position.coords.latitude + "," + position.coords.longitude);
}, function(error) {
if (unreliablePosition) {
console.log("using unreliable");
resolve(unreliablePosition.coords.latitude + "," + unreliablePosition.coords.longitude);
} else {
console.log("no data");
reject(error);
}
}, {
enableHighAccuracy: true,
timeout: 5 * 60E3,
maximumAge: 0
});
});
}
What I tried
The only question I found on stackoverflow that tackles the problem was this one which I tried, but it didn't seem to work (probably because it's from 2014). I created a folder called custom-plugins
and moved the plugin there instead of c.
I also tried removing ACCESS_COARSE_LOCATION
from the xml in an attempt to force the app to use ACCESS_FINE_LOCATION
, but then error function is called with PositionError {code: null, message: ""}
as soon as I call getCurrentPosition
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="my-app" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<icon src="www/logo.png" />
<name>my-app</name>
<description>
my application
</description>
<author email="dev@cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="geo:*" />
<platform name="android" />
<plugin name="cordova-plugin-whitelist" spec="^1.3.4" />
</widget>
package.json
{
"name": "my-app",
"displayName": "my-app",
"version": "1.0.0",
"description": "my app",
"main": "build.js",
"scripts": {
"build": "node build.js",
"debug": "node debug.js",
"test": "node test.js"
},
"keywords": [
"ecosystem:cordova"
],
"author": "me",
"license": "Apache-2.0",
"devDependencies": {
"cordova-android": "^9.1.0",
"cordova-browser": "^6.0.0",
"cordova-plugin-geolocation": "file:custom-plugins/cordova-plugin-geolocation",
"cordova-plugin-ionic-keyboard": "^2.2.0",
"cordova-plugin-network-information": "^2.0.2",
"cordova-plugin-whitelist": "^1.3.4"
},
"cordova": {
"plugins": {
"cordova-plugin-whitelist": {},
"cordova-plugin-ionic-keyboard": {},
"cordova-plugin-network-information": {},
"cordova-plugin-geolocation": {
"GPS_REQUIRED": "true"
}
},
"platforms": [
"android",
"browser"
]
}
}
AndroidManifest.xml
This file has been generated by cordova at ./platforms/android/app/src/main/
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="my-app" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-feature android:name="android.hardware.location.gps" android:required="true" />
</manifest>