Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Geolocation on Android always returning 'location unavailable' #4962

Closed
jonathan-chin opened this issue Aug 24, 2021 · 60 comments
Closed

Comments

@jonathan-chin
Copy link

jonathan-chin commented Aug 24, 2021

Bug Report

Capacitor Version

💊   Capacitor Doctor  💊 

Latest Dependencies:

  @capacitor/cli: 3.2.0
  @capacitor/core: 3.2.0
  @capacitor/android: 3.2.0
  @capacitor/ios: 3.2.0

Installed Dependencies:

  @capacitor/cli: 3.0.0
  @capacitor/core: 3.0.0
  @capacitor/android: 3.0.0
  @capacitor/ios: 3.1.2

[error] Xcode is not installed
[success] Android looking great! 👌

Platform(s)

Android 10

Current Behavior

When I try to call Geolocation.getCurrentPosition(), I always get an error: 'location unavailable'. I've tried this with no options and {enableHighAccuracy: true}.

I have the appropriate permissions set and the code works on PWA and iOS. The app has Location permission while in the foreground and Google Maps can get my location fine.

Expected Behavior

Geolocation.getCurrentPosition() should provide the lat/lng of the current position.

Code Reproduction

edit: basic repo set up here: https://github.com/jonathan-chin/capacitor-geocode-android-example
clicking on the get currentposition button will return location unavailable when running on a Google Pixel 3A on Android 10 through Android Studio.

it seems to have been an existing issue in the past #2854 but I am still experiencing it.

@jcesarmobile jcesarmobile added the needs reproduction needs reproducible example to illustrate the issue label Aug 25, 2021
@Ionitron
Copy link
Collaborator

This issue may need more information before it can be addressed. In particular, it will need a reliable Code Reproduction that demonstrates the issue.

Please see the Contributing Guide for how to create a Code Reproduction.

Thanks!
Ionitron 💙

@Ionitron Ionitron added the needs reply needs reply from the user label Aug 25, 2021
@jonathan-chin
Copy link
Author

@jcesarmobile @Ionitron just updated with a bare minimum repo.

@Ionitron Ionitron removed the needs reply needs reply from the user label Aug 25, 2021
@exomc
Copy link

exomc commented Aug 25, 2021

I've been using this plugin without any problems for weeks while developing my app. I've just updated all packages to the latest versions and now I am also experiencing this issue. Goes straight to error after giving the app permission. No error code or anything just 'location unavailable'

Ionic 6.17.0
Android Studio to Artic Fox | 2020.3.1 Patch 1

I'm getting the same thing on the emulator (with play store) as well as on my device. Web is fine.

Android build now generated the following warnings, not sure if they are relevant:

AGPBI: {"kind":"warning","text":"Using flatDirs should be avoided because it doesn't support any meta-data formats.\nCurrently detected usages:\n- repository flatDir used in: project ':app', project ':capacitor-cordova-android-plugins'","sources":[{}]}
AGPBI: {"kind":"warning","text":"Please remove usages of jcenter() Maven repository from your build scripts and migrate your build to other Maven repositories.\nThis repository is deprecated and it will be shut down in the future.\nSee http://developer.android.com/r/tools/jcenter-end-of-service for more information.\nCurrently detected usages in: root project 'android', project ':app', project ':capacitor-android', ...","sources":[{}]}

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
Use '--warning-mode all' to show the individual deprecation warnings.

@jonathan-chin
Copy link
Author

I updated the repo a second time to implement @ionic-native geolocation. this gives me a lat/lng while the capacitor implementation still returns 'location unavailable'.

@exomc
Copy link

exomc commented Aug 26, 2021

Having gone into Tools > SDK Tools in Android Studio and ticking the box for Google Play services in the SDK Tools tab, it works in the emulator now. Setting the location doesn't work, but at least do get a position.

Still can't get it to work on my Android device which is logged in to Play Store.

Seems to be some disconnect between Play Services and Capacitor / Android Studio.

@exomc
Copy link

exomc commented Aug 26, 2021

Native Geolocation works fine so am sticking with that!

@marcoagsa
Copy link

I have the same problem !
I removed the android platform and added it again and the problem remains

@jonathan-chin
Copy link
Author

I'm currently migrating my code to use Ionic Native since I have a tight deadline. I'd love to be able to use 100% Capacitor and am happy to switch back after this gets resolved.

@jcesarmobile jcesarmobile removed the needs reproduction needs reproducible example to illustrate the issue label Aug 26, 2021
@jcesarmobile
Copy link
Member

jcesarmobile commented Aug 26, 2021

I can't reproduce on the provided app, but buttons are working and returning locations. Tested on Android 9 and Android 11 devices.
What devices are you testing on? Android versions of the devices?
Which countries do you live in? The plugin uses com.google.android.gms:play-services-location dependency, play services might not be available in some countries. This should not be relevant, supposedly the Fused Location Provider is now available worldwide.

the cordova plugin uses the WebView location, so it's no different from using

navigator.geolocation.getCurrentPosition((position) => {
  console.log(position.coords.latitude, position.coords.longitude);
});

@jonathan-chin
Copy link
Author

jonathan-chin commented Aug 26, 2021

@jcesarmobile I tested on a physical phone by running it through Android Studio. the phone is:
Pixel3a Android 10 buildnumber QQ1A.200105.002
I'm in the US. Google Maps, MapQuest, and some random GPS apps I downloaded all seem to be working fine from the same phone.

I've also run in in the Android simulator:
Pixel 4 running Android 11

let me know if you need more info

@jcesarmobile
Copy link
Member

jcesarmobile commented Aug 26, 2021

Can you open Geolocation.java class on the capacitor-geolocation module and search for location unavailable?. There should be 2 occurrences. Change the first one to location null (or any other message) and run again.
Won't really help much, but just curious if you are getting location unavailable or a null location, which Google says can happen sometimes, but rarely.

@bildonia
Copy link

I'm seeing this issue on a Pixel 5 and Galaxy Tab A both running Android 11.

@jonathan-chin
Copy link
Author

it seems I'm getting it here:

                @Override
                public void onLocationAvailability(LocationAvailability availability) {
                    if (!availability.isLocationAvailable()) {
                        resultCallback.error("location YYY");
                        clearLocationUpdates();
                    }
                }

@jcesarmobile
Copy link
Member

And what happens if you remove the whole onLocationAvailability function?

@jonathan-chin
Copy link
Author

@jcesarmobile removing the function makes it work. I got lat/lng, altitude, speed, etc.

@jcesarmobile
Copy link
Member

🤔 that's really weird, why would onLocationAvailability fire and say it's not available but return a location if you ignore it?

@jonathan-chin
Copy link
Author

@jcesarmobile so I went off of this:
https://www.titanwolf.org/Network/q/f51ad29a-0a3e-42ca-a991-e460331ef8e3/y

if I push the app via Android studio (with onLocationAvailability still in), then reset my phone, I get results. if I spam the button, I will sometimes get location unavailable, but only like 1/30 times and the following key press works just fine (and when I say spam, I mean spam).

however, when I background the app and come back to it, I get location unavalable. BUT if I call the ionic native version once, I get results from capacitor for the next 4-5 keypresses. I can do this reliably.

@jcesarmobile
Copy link
Member

Yeah, I also saw that thread, but looked like a device bug.

I still can't reproduce, even backgrounding the app. And sadly removing the onLocationAvailability method is not a good solution as it makes getCurrentPosition hang when the location is disabled by the user as it's not able to detect that it's disabled but the onLocationResult doesn't get called neither.

Can you replace the whole sendLocation method with

@SuppressWarnings("MissingPermission")
public void sendLocation(
        boolean enableHighAccuracy,
        int timeout,
        final boolean getCurrentPosition,
        final LocationResultCallback resultCallback
    ) {
      fusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
      LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
      boolean networkEnabled = false;

      try {
        networkEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
      } catch (Exception ex) {}
      int lowPriority = networkEnabled ? LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY : LocationRequest.PRIORITY_LOW_POWER;
      int priority = enableHighAccuracy ? LocationRequest.PRIORITY_HIGH_ACCURACY : lowPriority;
      fusedLocationClient.getCurrentLocation(priority, null).addOnCompleteListener(new OnCompleteListener<Location>() {
        @Override
        public void onComplete(@NonNull Task<Location> location) {
          if (location.getResult() != null) {
            resultCallback.success(location.getResult());
          } else {
            resultCallback.error("no location");
          }
        }
      });
}

@jonathan-chin
Copy link
Author

I'm getting 4 compile errors:

cannot find symbol class OnCompleteListener
caused by this line:
fusedLocationClient.getCurrentLocation(priority, null).addOnCompleteListener(new OnCompleteListener() {

cannot find symbol class Task
caused by this line:
public void onComplete(@nonnull Task location) {

cannot find symbol class NonNull
also caused by this line:
public void onComplete(@nonnull Task location) {

method does not override or implement a method from a supertype
caused by this line:
@OverRide

@jcesarmobile
Copy link
Member

You might need to manually add this imports (sometimes Android Studio doesn't add them by default)

import androidx.annotation.NonNull;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

or putting the cursor over the unrecognized symbol and pressing alt+Intro can also import it

@jonathan-chin
Copy link
Author

@jcesarmobile sorry, I don't use Android Studio much; I have barely coded in Java in the last 15 years.

the new function seems to work well. I have not gotten a location unavailable ever during the 30 seconds I spammed the button.

this may be a fix! what is different?

@stevebrowndotco
Copy link

I can confirm that within the last week or so this plugin is reporting "location unavailable" on android.
I am somewhat reassured that this seems to be very recent for others here. Could this plugin be depending on something that is broken elsewhere?

  • It never works on Android (but used to)
  • It works on iOS
  • It works on PWA web app

@stevebrowndotco
Copy link

stevebrowndotco commented Aug 27, 2021

I can confirm that implementing this change to Geolocation.java fixes it for me

Although effectively this is a change in node_modules , so only a temporary solution.. (for now I am using patch-package)

@jcesarmobile
Copy link
Member

Don't worry, Android Studio can be annoying sometimes. Thanks for testing!

It uses a new method for getting a single location (at the moment the plugin starts tracking location and stops it when it get the first result). It was introduced in play-services-location 17.1.0 and is supposed to handle this kind of errors/problems better. On the other hand, it doesn't allow to configure the timeout, which could be considered a breaking change in the plugin, so we don't know when we would be able to do a new release with the fix.
I've created ionic-team/capacitor-plugins#571 for tracking the code change.

@jcesarmobile
Copy link
Member

looks like Google didn't remove 21.30.16 from play store as I just got it on my device

@AppskySpencer
Copy link

My Google Play Services version is 21.33.12 and I am still having the issue.

@jcesarmobile
Copy link
Member

I've reported this issue on google issue tracker
https://issuetracker.google.com/issues/198176818

@luisdalopez56
Copy link

I have been testing on an android 7 and using native ionic Location accuracy I have been able to change the precision to the user and this way it works, but the problem comes with Android 11, there is no way to make it work

@ChaminThilakarathne
Copy link

I have been tesing on GalaxyA32 (Android 11) the Geolocation plugin await Geolocation.getCurrentPosition(); is retuned
{"message":"location unavailable"} but it had been worked fine in 3 weeks ago. please give any solution asap. lot of users waiting for a fix.

@ignaciomarti
Copy link

Same issue... Temporarily solved by commenting out these lines in Geolocation.java

if (!availability.isLocationAvailable()) {
call.error("location unavailable");
clearLocationUpdates();
}

@jcesarmobile
Copy link
Member

@capacitor/geolocation 1.1.0 is out with a fix

@KevinKelchen
Copy link

KevinKelchen commented Sep 3, 2021

Awesome! 😀

Are there plans to release an update to Capacitor v2 with the same fix? I see someone has an open PR for it: #4992 . Thought it might be worth asking since some of us have yet to upgrade to v3 and given the level of severity of the issue. 🙂

For now I've manually made the changes in #4992 to node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/Geolocation.java and used patch-package so we can hotfix our app. We can then remove the patch if the fix lands in Capacitor v2 or when the day comes that we upgrade to v3.

Thanks so much!

@FahmiChaar
Copy link

@KevinKelchen
how you use patch-package ?
when i run npx patch-package @capacitor/core the output is ⁉️ There don't appear to be any changes. and patches folder did not created

@KevinKelchen
Copy link

@KevinKelchen
how you use patch-package ?
when i run npx patch-package @capacitor/core the output is ⁉️ There don't appear to be any changes. and patches folder did not created

It’s not @capacitor/core that’s being patched but rather @capacitor/android. Try changing the package name. 🙂

@FahmiChaar
Copy link

@KevinKelchen
how you use patch-package ?
when i run npx patch-package @capacitor/core the output is ⁉️ There don't appear to be any changes. and patches folder did not created

It’s not @capacitor/core that’s being patched but rather @capacitor/android. Try changing the package name. 🙂

thank you so much, it work now

@mtpultz
Copy link

mtpultz commented Sep 7, 2021

We followed these steps to patch (Thanks @KevinKelchen) and had to add an optional step 6 to have it run in Ionic AppFlow:

  1. Access @capacitor/android and update Geolocation.java using this PRs changes (https://github.com/ionic-team/capacitor/pull/4992/files)
  2. Run npx patch-package @capacitor/android
  3. Update package.json with "postinstall": "patch-package"
  4. npm install patch-package so dependency exists when npm install is run during Ionic AppFlow
  5. Commit the patch file and changes to package.json
  6. (Optional) If you get an error like "cannot run in wd [...]" add a .npmrc with unsafe-perm = true when using Ionic AppFlow since we can't use a non-root user

@jcesarmobile
Copy link
Member

We have released @capacitor/android 2.5.0 with the fix, but please, update to capacitor 3 as soon as possible, it's not that hard and most fixes won't be backported to capacitor 2.

@08-15at
Copy link

08-15at commented Sep 9, 2021

JFYI: looks like Google has updated Play-Services.
Version 21.33.13 seems to work with the old code....

@jcesarmobile
Copy link
Member

not working for me with that version

@08-15at
Copy link

08-15at commented Sep 9, 2021

strange...
seems as there could be some underlying Google code changes somewhere else: some customers reported, that it started working again after an automatic Android update on Sep. 3.
However it remained broken for others.
So I asked some of those customers with a working device to send me their Play-Services version-info, it was still 21.30.16, but my app started working again on their devices after an Android update on Sep. 3. without changes on my side.
On my devices and the simulator I could see a Play-Service version released on Sep. 3 in the Web PlayStore, but Play-Store let me only install the Aug. 28 version where it would fail on my devices.
I uploaded a workaround in place for my app Sept. 5, and I could update to your code, so no issue for me.
However today I got 21.33.13 from the PlayStore and I tried my (unpatched) app version and the previous failing Ionic Capacitor - Core Plugins Demo and it worked.

@krabien
Copy link

krabien commented Sep 9, 2021

For our users, it appears to be intermittent. One user reports 80% fail 20% success on getting a GPS fix.
I don't know what Play Services version they have.
Capacitor 2.5.0 fixes the issue on our testing environments, thanks so much Ionic team!

@NicolaiLolansen
Copy link

For our users, we have reports from 8th August, and 9th of september that location did not work for them. I can emulate a Pixel 2 API 28 that works fine in Android Studio.

The user on 8th of August has Android 10 on a Galaxy A41 and the user on 9th of September has Android 11 on a Oneplus Pro 9 5G.

The app we released worked on release, and has since seen reports of failure on the GPS. We use the Geolocation from capacitor/core and the manifest has the permissions included as the documentation says. Getting the play service versions has not been possible. Will try upgrading to 2.5.0 as @krabien said, and will see if that fixes it for us aswell

@Pendrokar
Copy link

Pendrokar commented Sep 15, 2021

capacitor/android 2.5
along with the dependency
capacitor/core 2.5

...does seem to fix the issue on an OnePlus 6, Android 10. But on an emulated Pixel 3 API 30, while Geolocation.getCurrentPosition does get called, it never receives a result. Not even a 'location unavailable' like previously.

@JamesWaterhouse
Copy link

@jcesarmobile how's this coming along? Any word from Google on sorting it out? I'm reluctant to have to submit new builds with updated Capacitor plugins if its not a certainty that it'll work still.

@jcesarmobile
Copy link
Member

Google said they reverted the changes last week and should work again, but play services updates takes time and not everybody gets them at the same time.

I would recommend updating as they don't recommend relying in isLocationAvailable, which the old versions used, but it's up to you.

@NicolaiLolansen
Copy link

Is there any official statement from google i can send to my users?

@jcesarmobile
Copy link
Member

No official statement as far as I know, only a comment on the issue I reported
https://issuetracker.google.com/issues/198176818

@filifunk
Copy link

filifunk commented Oct 1, 2022

Hi I get this 'location unavailable' issue everytime I try to get my location on my phone (pixel 4a, google play services 22.33.16) for the first 5 minutes or so. Then eventually I'm able to get a location. I'm trying to make it so that I don't have to wait 5-10 minutes for a location.

I'm not really able to understand java but I'm getting "location unavailable" from this code block. I know because I changed the error message so I knew it was coming from here:

	    
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(context);

            LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
            if (this.isLocationServicesEnabled()) {
                boolean networkEnabled = false;

                try {
                    networkEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                } catch (Exception ex) {}

                int lowPriority = networkEnabled ? Priority.PRIORITY_BALANCED_POWER_ACCURACY : Priority.PRIORITY_LOW_POWER;
                int priority = enableHighAccuracy ? Priority.PRIORITY_HIGH_ACCURACY : lowPriority;

                LocationRequest locationRequest = LocationRequest
                    .create()
                    .setMaxWaitTime(timeout)
                    .setInterval(10000)
                    .setFastestInterval(5000)
                    .setPriority(priority);

                locationCallback =
                    new LocationCallback() {
                        @Override
                        public void onLocationResult(LocationResult locationResult) {
                            Location lastLocation = locationResult.getLastLocation();
                            if (lastLocation == null) {
                                resultCallback.error("location unavailable test");
                            } else {
                                resultCallback.success(lastLocation);
                            }
                        }
                    };

                fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
            } else {
                resultCallback.error("location disabled");
            }
        } else {
            resultCallback.error("Google Play Services not available");
        }
    }

I tried following the issuetracker link and using the code from the #105 post about the PRIORITY_HIGH_ACCURACY, and copied it in and got a lot of errors. I also tried the solution of downgrading my gradle version but that gives me errors. Any recommendations for what I should do?

@connectMyClub
Copy link

We're having the same issue. All was fine a week or so ago. I'm assuming it's a Google Play Service bug, as it has been previously, and we just have to wait for a fix.

@ionitron-bot
Copy link

ionitron-bot bot commented Dec 10, 2022

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Dec 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests