I’m having a hard time debugging this issue. I’m using Capacitor’s geolocation functionality (and have been for a while). I recently had to replace my laptop and now it seems something in my environment is preventing geolocation from working in the Android emulator, even though it works everywhere else, including the browser, iOS simulator, and iOS devices (including published apps in the App Store).
UPDATE: Also works on a physical Android device and API < 30. I’ve updated the title to indicate that this issue is specifically with Android API 30. This may be something that needs to be addressed in the Capacitor Geolocation plugin.
Here’s the log from Android Studio.
2021-03-29 12:49:52.632 9838-9838/org.myapp.myapp D/Capacitor: Registering plugin: Geolocation
2021-03-29 12:49:56.129 9838-9943/org.myapp.myapp V/Capacitor/Plugin: To native (Capacitor plugin): callbackId: 51862699, pluginId: Geolocation, methodName: getCurrentPosition
2021-03-29 12:49:56.129 9838-9943/org.myapp.myapp V/Capacitor: callback: 51862699, pluginId: Geolocation, methodName: getCurrentPosition, methodData: {}
2021-03-29 12:49:56.397 9838-9919/org.myapp.myapp D/Capacitor: Sending plugin error: {"save":false,"callbackId":"51862699","pluginId":"Geolocation","methodName":"getCurrentPosition","success":false,"error":{"message":"location unavailable"}}
Ionic Info:
Ionic:
Ionic CLI : 6.13.1 (/usr/local/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 5.0.7
@angular-devkit/build-angular : 0.803.26
@angular-devkit/schematics : 8.3.26
@angular/cli : 8.3.26
@ionic/angular-toolkit : 2.2.0
Capacitor:
Capacitor CLI : 2.1.0
@capacitor/core : 2.4.7
Utility:
cordova-res : 0.15.3
native-run : not installed
System:
NodeJS : v15.10.0 (/usr/local/Cellar/node/15.10.0_1/bin/node)
npm : 7.5.3
OS : macOS Big Sur
Capacitor Info:
@capacitor/cli 2.1.0
@capacitor/core 2.4.7
@capacitor/android 2.4.7
@capacitor/ios 2.4.7
Usage (Location Service):
import { Injectable } from "@angular/core";
import { ProjectConfigService } from "../project-config/project-config.service";
import * as geolib from "geolib"; // https://www.npmjs.com/package/geolib
import { Plugins } from "@capacitor/core";
const { Geolocation } = Plugins;
@Injectable({
providedIn: "root"
})
export class LocationService {
userLocation: any;
nearby: any;
northerly: any;
nearbySortedEvent: any;
locationAware: boolean;
mapSettings = this.project.getMapSettings();
constructor(private project: ProjectConfigService) {}
isLocationAware(bool: boolean) {
return new Promise(resolve => {
this.locationAware = bool;
//console.log('Location aware: '+this.locationAware);
resolve(this.locationAware);
});
}
sortNortherly(stories: any) {
// used to control map marker z-axis stacking
return new Promise(resolve => {
let northerly = new Array();
stories.forEach(function(story: any) {
var distance = geolib.getDistance(
{ latitude: 90, longitude: 0 },
{ latitude: story.latitude, longitude: story.longitude },
10
);
story.northerly = distance;
northerly.push(story);
});
northerly.sort(function(a, b) {
return a.northerly - b.northerly;
});
this.northerly = northerly;
resolve(this.northerly);
});
}
sortStoriesListNearby(stories: any, reverse = false) {
// used for manual sort event on stories list
return new Promise(resolve => {
let displayUnit = this.mapSettings["distance_unit"];
this.getUserLocation().then(userLocation => {
if (userLocation !== false) {
let nearbySorted = new Array();
stories.forEach(function(story: any) {
var distance = geolib.getDistance(
{ latitude: userLocation["lat"], longitude: userLocation["lon"] },
{ latitude: story.latitude, longitude: story.longitude },
10
);
story.distance = []; // meters
story.distance["meters"] = distance;
story.distance["kilos"] =
geolib.convertDistance(distance, "km").toFixed(2) + " km";
story.distance["miles"] =
geolib.convertDistance(distance, "mi").toFixed(2) + " mi";
story.distance["display"] = story.distance[displayUnit];
nearbySorted.push(story);
});
if (!reverse) {
// closest
nearbySorted.sort(function(a, b) {
return a.distance.meters - b.distance.meters;
});
} else {
// furthest
nearbySorted.sort(function(a, b) {
return b.distance.meters - a.distance.meters;
});
}
this.nearbySortedEvent = nearbySorted;
resolve(this.nearbySortedEvent);
} else {
//console.log('something went wrong...'); // @TODO: add toast
this.nearbySortedEvent = stories;
resolve(this.nearbySortedEvent);
}
});
});
}
sortByProximity(stories: any, n: number) {
// used to sort by location on startup/refresh for discover view
return new Promise(resolve => {
let displayUnit = this.mapSettings["distance_unit"];
this.getUserLocation().then(userLocation => {
if (userLocation !== false) {
let nearby = new Array();
stories.forEach(function(story: any) {
var distance = geolib.getDistance(
{ latitude: userLocation["lat"], longitude: userLocation["lon"] },
{ latitude: story.latitude, longitude: story.longitude },
10
);
story.distance = []; // meters
story.distance["meters"] = distance;
story.distance["kilos"] =
geolib.convertDistance(distance, "km").toFixed(2) + " km";
story.distance["miles"] =
geolib.convertDistance(distance, "mi").toFixed(2) + " mi";
story.distance["display"] = story.distance[displayUnit];
nearby.push(story);
});
nearby.sort(function(a, b) {
return a.distance.meters - b.distance.meters;
});
if (n !== 0) this.nearby = nearby.slice(0, n);
resolve(this.nearby);
} else {
this.nearby = false;
resolve(this.nearby);
}
});
});
}
getUserLocation() {
return new Promise(resolve => {
Geolocation.getCurrentPosition().then(
position => {
this.userLocation = {
lat: position.coords.latitude,
lon: position.coords.longitude
};
this.isLocationAware(true);
resolve(this.userLocation);
},
_err => {
this.isLocationAware(false);
this.userLocation = false;
resolve(this.userLocation);
}
);
});
}
}
Permissions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" />