Enabling "High Accuracy" Location using Settings API in Google Play Service - android

I'm trying to enable the location from application using Settings API. In location dialog it shows message Use WiFi and cellular networks for location. On selection of Yes it is enabling the location but not the GPS.
But while I was playing with Google Maps in same device, it displays the message
Use GPS, WiFi and cellular networks for location as like below screenshot.
And this is enabling the GPS also. How can I achieve the same as Google Maps.
Before posting here I hope I have checked all the possible options. Find my tryouts list below.
I have set the priority as HIGH_ACCURACY and min interval to 5 seconds
locationRequest = LocationRequest.create();
// Set the priority of the request
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval to 10 seconds
locationRequest.setInterval(1000 * 10);
// Set the fastest update interval to 5 seconds
locationRequest.setFastestInterval(1000 * 5);
Using only FINE_LOCATION permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Also referred few links but nothing gave exact solutions. All I need is I would like to enable the location with HIGH_ACCURACY by default which enables the GPS Any help on this?

I had this problem, but after clicking the YES button to permit use GPS, the activity stops and runs the method onPause and then the activity begins in the method onResume.
So my solution was start again the localizacion in onResume method
#Override onResume public void () {
//your code
         LocationRequest = LocationRequest.create ();
// Set the priority of the request
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval to 10 seconds
locationRequest.setInterval (1000 * 10);
// Set the fastest update interval to 5 seconds
locationRequest.setFastestInterval (1000 * 5);
.....
//start again the localizacion
LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locRequest, this);

Related

Android Fused Location Won't Deliver Periodic Updates

I want to get a hard location fix every certain minutes & a soft location fix every certain minutes and if user has moved more then certain meters. I been testing the logic with following piece of code walking (tried it with larger parameters as well while driving) but it doesn't really return me periodic location fixes. It would return a location fix right away when request starts then sometime return 1 location fix few minutes later that but then for up-to an hour it won't return a location fix.
LocationRequest locationRequest = LocationRequest.create();
int priority = PRIORITY_BALANCED_POWER_ACCURACY;
locationRequest.setPriority(priority);
locationRequest.setInterval(localInterval); //set to 6 minutes
locationRequest.setFastestInterval(localFastestInterval); //set to 3 minutes
locationRequest.setSmallestDisplacement(smallestDisplacement); //set to 10 meters
locationRequest.setNumUpdates(numUpdates); //set to Int.MAX_VALUE
locationRequest.setExpirationDuration(expirationDuration); // set to Long.MAX_VALUE
LocationServices.FusedLocationApi.requestLocationUpdates(locationClient, locationRequest, pendingIntent);
If I set displacement to 0 then I get periodic location updates. Any idea what is going on?
After long exhaustive testing & experimentation I've found that if you don't call setFastestInterval you will get periodic updates exactly according to the interval set with setInterval.
However as other applications can cause location fixes to be delivered very fast to you so just put a check for ignoring location fixes delivered faster than a certain threshold of time passed.
According to documentation: If setFastestInterval(long) is set slower than setInterval(long), then your effective fastest interval is setInterval(long) but that doesn’t happen: e.g. setting following parameters should give you a hard location fix every 1 minute but it does not (on Marshmallow at-least):
interval = 1 min
fastestInterval = 20 min
displacement = 0
If anyone can disprove my findings with a piece of code that would be great.

Checking the location every 10 minutes in the background

My requirement is to check the location of the device every 10 minutes using a background service. So the basic gist of what should happen every 10 minutes is this -
Start the service.
Wait a minute (maximum) for the listener to get a location, once the location is taken, remove the listener and then stop the service.
If the listener doesn't respond, use getLastKnownLocation(), remove the listener and then stop the service.
If the GPS is off, it reports to the app (this step is working fine)
What I have tried doing till now -
Made a service which is triggered every 10 minutes using an AlarmManager
Added a Location Listener inside this service.
onLocationChanged() from the LocationListener has the method - stopSelf() included, so that the service ends after receiving a location. However, this method is called a numerous times. I checked that while debugging. Is this because there are many instances of onLocationChanged() called ?
I don't need an entire code as the answer, I would rather appreciate a strategy I should adopt which will fulfil my requirements without hurting the battery much. As with my approach, unless and until the location is found, the GPS remains ON draining the battery constantly.
Instead of alarm manager which is scheduling each 10 min, use the FusedLocationAPI and location request in order to get accurate location.
LocationRequest mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);//Change to PRIORITY_HIGH_ACCURACY for more accurate.
mLocationRequest.setInterval(600000); // Update location every 10 minute
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Call this method whenever you need the location
/**
* Get the Location Detail from Fused Location API.
* #param mContext
* #return
*/
private Location getLocationDetails(Context mContext) {
Location location = null;
if (mGoogleApiClient != null) {
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG,"Location Permission Denied");
return null;
}else {
location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
}
return location;
}
try with this
// The minimum distance to change updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 10; // 10 minute
for more info example try with this
Try with this link click here
onLocationChanged() from the LocationListener has the method - stopSelf() included, so that the service ends after receiving a location. However, this method is called a numerous times. I checked that while debugging. Is this because there are many instances of onLocationChanged() called ?
Basically, when you receive the first location, also stopping the service via stopSelf() thats okay too.
But how the onLocationChanged method being called numerous time ?
Dont you remove location updates when the service shutting down ?

Cordova geolocation watchPosition frequency is higher than the options allow it

in my ionic/angularjs application I'm using the geolocation plugin: https://github.com/apache/cordova-plugin-geolocation
Like in the documentation I use this to configure the watch:
var watchOptions = {
frequency : 10*1000,
timeout : 60*60*1000,
enableHighAccuracy: true // may cause errors if true
};
watch = navigator.geolocation.watchPosition(on_success,on_error,watchOptions);
But however on android the frequency is much higher than 10 seconds (about 0.5 Seconds). On iOS it works great. What is the problem here?
Updated in light of comments below
There is no frequency parameter available in the geolocation options for watchPosition() hence any value you pass will be ignored. The success callback registered via watchPosition() is invoked each time the native location manager receives a position update from the GPS hardware (in the case of enableHighAccuracy=true) so it's not called on a fixed interval.
The native location managers (both Android and iOS) are event-driven, i.e. they receive updates from the GPS hardware as and when it delivers them at a non-fixed interval. Hence trying to apply a fixed frequency to this is trying to fit a square peg in a round hole - you cannot demand that the GPS hardware deliver you a location update exactly ever N seconds.
While you can call getCurrentPosition() on a fixed interval, this method simply returns last received position or requests a new one.
If the problem is that the updates are too frequent, you could log the time each update is received at, and only accept the next update after N seconds, e.g.
var lastUpdateTime,
minFrequency = 10*1000,
watchOptions = {
timeout : 60*60*1000,
maxAge: 0,
enableHighAccuracy: true
};
function on_success(position){
var now = new Date();
if(lastUpdateTime && now.getTime() - lastUpdateTime.getTime() < minFrequency){
console.log("Ignoring position update");
return;
}
lastUpdateTime = now;
// do something with position
}
navigator.geolocation.watchPosition(on_success,on_error,watchOptions);
This, however, will not stop the device requesting updates more frequently, hence consuming a relatively large amount of battery.
The native Android LocationManager does allow you to specify a minimum time between updates when requesting location in order to minimise battery drain, however cordova-plugin-geolocation on Android doesn't implement use LocationManager directly, but instead uses the W3C Geolocation API Specification in the native webview, which does not allow you to specify this.
However, you can use this plugin to do this: cordova-plugin-locationservices
It will allow you to specify:
interval: Set the desired interval for active location updates, in milliseconds.
fastInterval: Explicitly set the fastest interval for location updates, in milliseconds.

Update location every 5sec android

Hi I want get user location for every 5sec and user can change that duration like 10sec, 15sec upto 30sec i have spinner to choose this option
this is my request
private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(5000) // 5 seconds
.setFastestInterval(16) // 16ms = 60fps
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
this is initiate my start update
private void startPeriodicUpdates(int intervel) {
stopPeriodicUpdates();
REQUEST.setInterval(intervel);
mLocationClient.requestLocationUpdates(REQUEST, this);
// mConnectionState.setText(R.string.location_requested);
}
I can pass user selected interval to startPeriodicUpdates() method like startPeriodicUpdates(5000), startPeriodicUpdates(15000). But they location update duration working fine 15sec and more than 15sec
If i give 5sec or 10 sec the location update is running for every second
06-18 18:46:23.638: I/Location(2860): Location Changed Location[fused 65.966697,-18.533300 acc=4 et=+1h0m13s881ms alt=15.044444]
06-18 18:46:24.642: I/Location(2860): Location Changed Location[fused 65.966697,-18.533300 acc=4 et=+1h0m14s883ms alt=15.044444]
06-18 18:46:25.642: I/Location(2860): Location Changed Location[fused 65.966697,-18.533300 acc=4 et=+1h0m15s883ms alt=15.044444]
log show time interval for 23, 24, 25 please give your ideas.
The setInterval method is not exact. This is mentioned in the documentation.
Also, use the same interval for setFastestInterval and setInterval to prevent your app from receiving location updates faster than the the interval you specified in setInterval.
Just add REQUEST.setFastestInterval(intervel); to your startPeriodicUpdates method.

Android, Location Request, set expiration duration doesn't work

I'm using new API of location which had been introduced in I/O 2013.
It works fine and I have no problem with its results. My problem is when I set setExpirationDuration(WHATEVER_MILLIS) to whatever millis however it works for one minutes.
This is my code:
LocationRequest locationRequest = LocationRequest.create()
.setInterval(10 * 60 * 1000) // every 10 minutes
.setExpirationDuration(10 * 1000) // After 10 seconds
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
When I run the app, satellite indicator will be displayed in tray so, I expect to see it just 10 seconds. However, it will be disappear after a minute.
Any suggestion or comments would be appreciated. Thanks.
Since it seems to be a real problem in Android, a workaround could be a Handler to remove location updates manually.
listHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0) {
mLocationClient.removeLocationUpdates(MyActivity.this);
//Location Updates are now removed
}
super.handleMessage(msg);
}
};
After you request for location updates (for a maximum duration of 10s) you call this Handler, of course delayed for 10s.
myLocationClient.requestLocationUpdates(...);
listHandler.sendEmptyMessageDelayed(0, 10000);
This makes sure, that after 10s your location updates are removed.
In the documentation (https://developer.android.com/reference/com/google/android/gms/location/LocationRequest.html#setExpirationDuration(long))
It says that:
"The duration begins immediately (and not when the request is passed to the location client), so call this method again if the request is re-used at a later time."
One would expect this duration to start when following line is called:
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, this);
But, documentation states this duration begins when request object is created.

Categories

Resources