Skip to content
This repository has been archived by the owner on May 7, 2024. It is now read-only.

Location doesn't work when using GPS or other location providers #65

Open
benjymous opened this issue Sep 24, 2012 · 27 comments
Open

Location doesn't work when using GPS or other location providers #65

benjymous opened this issue Sep 24, 2012 · 27 comments

Comments

@benjymous
Copy link
Owner

Should be a simple fix

@benjymous
Copy link
Owner Author

Would that be smart enough to switch between GPS and cell location if the user turns gps on and off whilst the app is running, or would we need to detect the state change and reinitialise the location listener?

@firetech
Copy link
Collaborator

That, I can't answer. Probably not. :/

@DiogoNeves
Copy link

Not entirely sure if I understood the problem but, regarding location...
When you request updates from the LocationManager it will be associated with a specific provider (even if you pass a Criteria in). You should then listen for the onProviderDisabled event and get the best active provider again.
This might complicate things a bit again because, if you want accuracy you'll have to manage when GPS becomes active again even if you're using another active location provider.

Anyway, so far, the best advice on location I've seen was here:
http://android-developers.blogspot.co.uk/2011/06/deep-dive-into-location.html

But maybe I didn't understand the problem hehe :)

@benjymous
Copy link
Owner Author

Yeah - put simply it currently just uses the extra-course cell location provider, which fails entirely on devices that don't have cell radios (e.g. Nexus 7). What we really want would be for it to automatically use gps or wifi based location if those are available, but fall back to cell based location if not.

It only updates location every half hour, or so, but ideally it'll use as little power as possible.

I'll have a look at that example and see if I can rework the existing code to match its suggestions.

@DiogoNeves
Copy link

If it isn't for real-time location tracking, what do you think about using the Last Known Location as in the example (under Freshness means never having to wait)?
Basically, you'd have to setup your own timer for it but you could consider that for scarse updates is basically the same as when you just started the app.
You don't even need to only get location from active sources only. It might be the case that GPS was disabled fairly recently and is still a reliable position :)

What I mean with this is, the code from that example can be used almost as-is :)

I hope this helps (I'm almost getting my watch! YEAH! I could look into this after if you don't mind, I'm really excited! hehe)

@benjymous
Copy link
Owner Author

It already does check for the most recent update when it does a weather refresh, in case the OS has a newer location than the one it was last notified about - the main issue is that it won't activate and scan with GPS unless you actively tell it to.

Btw, even without a watch you can still experiment with the app - if you tick the "Show fake watches" option in Preferences/Device, then open the Select Watch option, you'll see a "Fake digital watch" entry - select that, and MWM will pretend it's connected to a digital watch - you'll be able to see the location and weather update status on the status tab, and will be able to see what the idle screen(s) look like on the widgets tab, to see what weather data it's pulled in.

@sdemills
Copy link

I've used location in some of my Android Apps and I'm sure you can get the
Location Manager to give you the best fix it can without specifying whether
or not it should use GPS. Isn't that what we need here? Or have I
misunderstood - in which case please either ignore or put me right :)

On 11 October 2012 12:04, Richard Munn [email protected] wrote:

It already does check for the most recent update when it does a weather
refresh, in case the OS has a newer location than the one it was last
notified about - the main issue is that it won't activate and scan with GPS
unless you actively tell it to.

Btw, even without a watch you can still experiment with the app - if you
tick the "Show fake watches" option in Preferences/Device, then open the
Select Watch option, you'll see a "Fake digital watch" entry - select that,
and MWM will pretend it's connected to a digital watch - you'll be able to
see the location and weather update status on the status tab, and will be
able to see what the idle screen(s) look like on the widgets tab, to see
what weather data it's pulled in.


Reply to this email directly or view it on GitHubhttps://github.com//issues/65#issuecomment-9336108.

@benjymous
Copy link
Owner Author

Yeah, we don't even need a particularly accurate fix (we're just trying to get weather for the current town/city, after all) - so really we just need a simple way to get a fairly recent location every time we do a weather refresh, in a manner that will work on devices without cell radios.

So ( wifi location || cell location || gps location ) I guess.

@DiogoNeves
Copy link

Try using this:

LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = manager.getBestProvider(criteria, false);
Location location = manager.getLastKnownLocation(provider);

(warning that was from top of my head, needs a bit of testing...)
That should give you a location and I don't mind looking at doing the 'proper' get the best known location later.

Don't forget to add

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

to your manifest ;) (FINE_LOCATION also includes COARSE permission so you only need that one ;) )

@DiogoNeves
Copy link

By the way, can you point me to the place where the Weather update happens? :)

@benjymous
Copy link
Owner Author

@DiogoNeves
Copy link

Finally started looking into it! hehe
Can you see the diff? https://github.com/DiogoNeves/MWM-for-Android/compare/fix-location

At the moment, anything older than Gingerbread will only use network (which I will change tomorrow or so).
On old devices I'm planning on listening for provider changes with the normal listener and switch to the current best active provider.
I'll have to profile the battery on that one though.

Anyway, if you could start having a quick look at the code, anything stupid, just let me know hehe :)

(I'm experimenting with fluent pattern which I think fits the purpose but let me know if you don't like the style hehe)

@benjymous
Copy link
Owner Author

Yeah, looks good so far.

I wouldn't worry too much about adding new functionality for pre-gingerbread, as long as the network location still works - the main issue is location on tablets that don't have a cell radio, of which the vast majority will be running 3.0+

(Only 4% of MW-CE's users are still on 2.1/2.2)

So really, we want something like

  • Use GPS if available (but not in a way that is detrimental to battery life)
  • if GPS disabled, then use wifi location
  • if wifi disabled, or can't get a location from the ssid, then use cell location

The current code only updates every half hour, or so - If you're manually polling instead of using the listener, can you wrap that into the existing weather update refresh?

@DiogoNeves
Copy link

Ok, great! :)
I'm not pulling at the moment but using the Intent based interface.
I've also moved the location updates into their own class to make it easier to maintain.
If we can neglect pre-gingerbread, I won't spend much more time on it then and will leave the best active provider on.

One thing I just noticed... if we have GPS enabled, as we only update every 30 mins... that means it'll go off between updates (unless another app is using it).
I just got this realisation now! (I think I was too sleepy yesterday!)

Either we conclude that we don't need GPS's accuracy for the weather (which I don't think it's the point) or I'll actually start pulling the location using that last best known location and only triggering the update when it isn't good enough (like the article I shared does).
This avoids waking up the GPS but still using it's location if it was updated recently.
I'm thinking about using the available position if it was collected on the last 5 mins, otherwise trigger an update. Minimal battery cost, highest accuracy, possibly 5 mins old.

What do you think?

I'm finishing something else and I'll look into this next :)

@sdemills
Copy link

My 2p/2c worth:-

The weather doesn't vary much within the location of a single cell tower so
whilst we're only using the location for weather I don't think we need
GPS. We can't get the forecast at all unless we have a signal from a cell
tower and I would have thought that location would be sufficiently
accurate?

I use Wunderground for weather because they are more accurate than the Met
Office in my opinion, and they zero in closer to the required location, but
often to get a forecast they are decoding the information from the METAR
from the local airport and that is often more than a cell tower away; for
local conditions they will use a local weather station if one is available

  • for example: Ruddington UK often uses data from the weather station on
    the roof of my house since I provide a 10 minute real time feed into
    Wunderground - if someone checks roughly 5 minutes between my feeds then
    they get conditions from 7 miles away because it is fresher so Wunderground
    obviously consider fresher being more important than closer as long as it's
    close enough.

Hope that helps - end 2p/2c :)

On 24 October 2012 00:25, Diogo Neves [email protected] wrote:

Ok, great! :)
I'm not pulling at the moment but using the Intent based interface.
I've also moved the location updates into their own class to make it
easier to maintain.
If we can neglect pre-gingerbread, I won't spend much more time on it then
and will leave the best active provider on.

One thing I just noticed... if we have GPS enabled, as we only update
every 30 mins... that means it'll go off between updates (unless another
app is using it).
I just got this realisation now! (I think I was too sleepy yesterday!)

Either we conclude that we don't need GPS's accuracy for the weather
(which I don't think it's the point) or I'll actually start pulling the
location using that last best known location and only triggering the update
when it isn't good enough (like the article I shared does).
This avoids waking up the GPS but still using it's location if it was
updated recently.
I'm thinking about using the available position if it was collected on the
last 5 mins, otherwise trigger an update. Minimal battery cost, highest
accuracy, possibly 5 mins old.

What do you think?

I'm finishing something else and I'll look into this next :)


Reply to this email directly or view it on GitHubhttps://github.com//issues/65#issuecomment-9722301.

@DiogoNeves
Copy link

That's a good point! ;)
I'd like to avoid switching GPS on, on purpose as well, but that does mean that trading freshness for accuracy might be a mistake...
What do you think of using getLastBestKnownLocation and pulling it every half an hour (and using the lowest powered solution for a quick update if the location is too old)?
This would use whatever is best at minimal cost, because we wouldn't turn anything on (unless we don't have a choice).

@benjymous
Copy link
Owner Author

Yeah, the weather is (currently) never updated more frequently than every half hour, anyway, so the location doesn't need to be that up to date, though ideally you want to keep it in sync, so that the location will be updated before the weather update, rather than afterwards.

@firetech
Copy link
Collaborator

There should probably be a setting where you can choose to allow GPS usage
or not... People (including myself) tend to be picky about what to allow,
battery wise. Frequent usage of GPS can kill your battery quickly.

On 24 October 2012 15:38, Diogo Neves [email protected] wrote:

That's a good point! ;)
I'd like to avoid switching GPS on, on purpose as well, but that does mean
that trading freshness for accuracy might be a mistake...
What do you think of using getLastBestKnownLocation and pulling it every
half an hour (and using the lowest powered solution for a quick update if
the location is too old)?
This would use whatever is best at minimal cost, because we wouldn't turn
anything on (unless we don't have a choice).


Reply to this email directly or view it on GitHubhttps://github.com//issues/65#issuecomment-9739481.

@sdemills
Copy link

I quite like that suggestion.

On 24 October 2012 14:38, Diogo Neves [email protected] wrote:

That's a good point! ;)
I'd like to avoid switching GPS on, on purpose as well, but that does mean
that trading freshness for accuracy might be a mistake...
What do you think of using getLastBestKnownLocation and pulling it every
half an hour (and using the lowest powered solution for a quick update if
the location is too old)?
This would use whatever is best at minimal cost, because we wouldn't turn
anything on (unless we don't have a choice).


Reply to this email directly or view it on GitHubhttps://github.com//issues/65#issuecomment-9739481.

@DiogoNeves
Copy link

Ok, here's another version, this time with pulling :)
https://github.com/DiogoNeves/MWM-for-Android/compare/pull-location

It uses whatever is the best available location and requests a single update if it isn't good enough.
At the moment, whenever we have to request a single update, that will trigger the twice...
I'm thinking about returning a boolean on the RefreshLocation() for cases when the location isn't good and ignore the weather update until the next update comes through.

What do you think?

@DiogoNeves
Copy link

I forgot to mention, it's possible to tweak the settings of the location finder, for example, if we do create an option for using GPS or not, the best way to go about it would be to set a new criteria like:

Criteria criteria = new Criteria();
if (useGPS)
    criteria.setAccuracy(Criteria.ACCURACY_HIGH);
else
    criteria.setPowerRequirement(Criteria.POWER_LOW);

locationFinder.setCriteria(criteria);

if you set it to low power, it'll still use an accurate location if it is available in the getLastBestKnownLocation() but won't turn the GPS on if it sends the single request.
This is actually the default behaviour at the moment...

To summarise:
Prefer accurate available locations but only request new ones from low powered providers :)

@DiogoNeves
Copy link

I'm not entirely sure if I should do this but...
On the new code I'm just finishing, if the location isn't good enough, I'm setting the LocationData.received to false and skip the weather update until the next update (which should be soon).
Is that ok?

@DiogoNeves
Copy link

Ok, submitted another change (the diff link should still work :) )

@benjymous
Copy link
Owner Author

Setting LocationData.received to false will cause all the weather widgets to display a "waiting for location" message, so it's better to just leave the previous known location in place if you're unable to get a new one - weather from the wrong location is better than no weather at all!

@DiogoNeves
Copy link

ok, I'll revert to the previous commit which didn't cause that hehe

@DiogoNeves
Copy link

Review that one :) doesn't set the received flag

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants