*Please have a look at the below written source code lines and suggest:-*
In the below mentioned code lines I am trying to request for GPS and Network location in every 60 seconds.
if (gps_enabled)
{
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 0, locationListenerGps);
}
if (network_enabled)
{
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0,
locationListenerNetwork);
}
Below mentioned is the code for location change listeners:-
LocationListener locationListenerGps = new LocationListener()
{
public void onLocationChanged(Location location)
{
mCurrentGpsLocation = location;
String userCurrentGpsLocation = findUserAddress(mCurrentGpsLocation, mPreviousGpsLocation);
mPreviousGpsLocation = location;
for(int i = 0, size = mLocationUpdateListeners.size(); i<size; i++)
{
LocationUpdateListener listener = mLocationUpdateListeners.get(i);
listener.recieveGpsNotification(userCurrentGpsLocation);
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
LocationListener locationListenerNetwork = new LocationListener()
{
public void onLocationChanged(Location location)
{
mCurrentNetworkLocation = location;
String userCurrentNetworkLocation =findUserAddress(mCurrentNetworkLocation, mPreviousNetworkLocation);
mPreviousNetworkLocation = location;
for(int i = 0, size = mLocationUpdateListeners.size(); i<size; i++)
{
LocationUpdateListener listener = mLocationUpdateListeners.get(i);
listener.recieveNetworkNotification(userCurrentNetworkLocation);
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
And on receiving location change event for GPS and Network, I simply call my listeners recieveGpsNotification() and recieveNetworkNotification() methods respectively.
Logic of recieveGpsNotification() are as follows :-
public void recieveGpsNotification(String gpsLocation)
{
sendEmail();
}
**Problems :-
1) I expect call to sendMail() should come after every 60 sec but I am receiving notifications very frequently and after 4-5 notifications my application crashes. Please help if you see any error in implementation logic.
2) Will i also receive notifications for GPS even when my activity is in pause state or in stopped state, because i want to receive notification even when my activity is in background or it is stopped?
Additional Query :-
Whenever android framework provides us with GPS location updates, every time notification come through a different thread or is it the thread that request for notifications?
Thanks in Advance.
**
Try adding a min distance to each update. Also consider grouping the updates together for your sendEmail() method
Move your Location Listener logic into a Service that runs in the background. This will keep the updates coming. However, be aware that GPS updates are awful for battery life and users will not be happy to see GPS trying to get a lock all the time.
I believe those updates happen on the thread in which they are declared. So you should move your findUserAddress() method and other complex operations to a different thread.
Also, You should only use one method to get GPS updates. The normal use case is to try GPS Adapter, if not enabled or preset, fall through to use the Network listener. Since you have both you will be getting both updates on different intervals.
Related
I have tried (but in vain) to force request GPS location updates on my Android Widget (Android Oreo).
The widget is set to update every 15-20 minutes and fetch the current location of the phone and display.
However, it only picks up the location of the phone where it was installed and subsequent runs don't return a new location even when the phone moves.
I read through the solution provided here How does it work - requestLocationUpdates() + LocationRequest/Listener and implemented it, but it doesn't seem to help.
LocationManager locationManager = (LocationManager)
context.getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
300000L, 500.0f, new LocationListener() {
#Override
public void onLocationChanged(android.location.Location location) {
if(location != null)
{
LocationPreferences.setLastLocationLatLon(context,location);
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
});
Having said that, it is more reliable when it's in one of the activities (and not in a widget), but given that the widget is supposed to perform background location updating, it doesn't work, the onlocationchanged never gets called (I'm sensing it's silently killed in the background)
Has anyone created/ worked with Android widgets using GPS on Oreo? Any help in the right direction will be appreciated. Thank you very much in advance.
I have an AlarmManager that triggers every 30 minutes to an IntentService, and this intent service is to get the user's location each time. I have 2 ways of getting location: first it checks the getLastKnownLocation(), and if it was within the last 2 minutes it uses that, this part works perfectly.
The second way is if the last location was old or returns null, in which I want to get the new location once. For some reason this never calls onLocationChanged(). This results in my IntentService not returning coordinates much of the time, it only returns them if the getLastKnownLocation() was recent.
Here is my code for how it is set up, why is it that if I want to get a new location, it is never called? Check the comments in the code to see what is called and what is never called.
LocationListener locationListener;
LocationManager locationManager;
private final double MIN_COORD_DIFF = 0.0006;
public CoordinateAlarmReceiver(){
super("CoordinateAlarmReceiver");
}
#Override
protected void onHandleIntent(Intent intent) {
//THIS IS CALLED CORRECTLY
MyLog.i("coordinate alarm received");
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location lastLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//if last location was in past 2 minutes, use that
if(lastLocation != null && lastLocation.getTime() > Calendar.getInstance().getTimeInMillis() - 2 * 60 * 1000) {
//THIS IS CALLED CORRECTLY
storeLocation(lastLocation);
MyLog.i("Last location was recent, using that");
}
else { //otherwise get new location
//THIS IS CALLED CORRECTLY
MyLog.i("Last location was old, getting new location");
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//THIS IS NEVER CALLED
MyLog.i("Got new coordinates");
storeLocation(location);
locationManager.removeUpdates(this);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
}
You should use a Service instead of a IntentService. The IntentService finish when complete the task however, the service is running and can listen the location change events. Try to use a service.
Hope it helps you!!
My app uses google map to show user's location in real time. Therefore I would like it to be updated with every data change on my Parse server.
I've looked all over the net and as I see it I have 3 options:
using syncAdapter - the problem is that everywhere it is written that it does not meant for real time data transfer (I don't really understand why), on other hand it must be more efficient than updating every 5 sec.
using asyncTask - the problem is that it probably consumes a lot of battery and data usage to run it every 5 sec.
using service - same problem as asyncTask.
As i'm very confused, please help me understand what is the appropriate way to implement my real time map.
Thank's all
The best way i know is to use LocationListener to update the location only if it has been changed. You can use the onLocationChanged() method to update the location.
public class LocationHelper {
private LocationManager locationManager;
private Location currentLocation;
public LocationHelper(Context context) {
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
locationManager.removeUpdates(locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
}
public void setLocation(Location location) {
currentLocation = location;
}
private final LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
setLocation(location);//Only update location if it has changed.
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
};
}
If the location hasn't been changed, you can just remember the last known location.
I need to check whether GPS is locked in my application. I am able to check whether GPs is enabled in the phone. But once the GPS is locked, while running the application, it gets unlocked and I noticed that the GPS icon of the phone is blinking. I need to show an animation similar to that of phone in my application to acknowledge the user the GPS is unlocked. Anybody who knows the solution please post it.
Thanks in advance....
This is what I use. Start your animation when you requestLocationUpdates and end it when you get the onLocationChanged call. See my code below, it should solve your issue.
public class YourLocationClass implements LocationListener {
private LocationManager lm;
public void getLocation(Context ctx) {
lm = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 15000, 25, this);
//START YOUR ANIMATION
}
public void onLocationChanged(Location location) {
//HERE YOU STOP YOUR ANIMATION AND GET NEW LOCATION
}
public void onProviderDisabled(String provider) {
// DO SOME STUFF
}
public void onProviderEnabled(String provider) {
// DO SOME STUFF
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// DO SOME STUFF
}
}
I'm using the code shown below to get an updated value for location every time a button is clicked. When my activity is resumed I get an update every second, so that when I call getLastKnownLocation I expect to have a location that have been updated in the last second.
Is that the correct way to do that?
I would expect the onLocationChanged event to be triggered every time I execute a 'geo fix' command (or max after 1s since I request update every 1s), but it's only triggered the first time. Why?
Any help/suggestion welcome!
Thanks
package org.digitalfarm.atable;
...
public class Atable extends Activity {
private Button mSearchButton;
private TextView mytext;
private LocationManager locationManager;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSearchButton = (Button)this.findViewById(R.id.button);
mytext = (TextView) findViewById(R.id.dude);
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
mSearchButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
}
});
}
//Start a location listener
LocationListener onLocationChange=new LocationListener() {
public void onLocationChanged(Location loc) {
//sets and displays the lat/long when a location is provided
String latlong = "Lat: " + loc.getLatitude() + " Long: " + loc.getLongitude();
mytext.setText(latlong);
}
public void onProviderDisabled(String provider) {
// required for interface, not used
}
public void onProviderEnabled(String provider) {
// required for interface, not used
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
// required for interface, not used
}
};
//pauses listener while app is inactive
#Override
public void onPause() {
super.onPause();
locationManager.removeUpdates(onLocationChange);
}
//reactivates listener when app is resumed
#Override
public void onResume() {
super.onResume();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,100.0f,onLocationChange);
}
}
The time, specified in requestLocationUpdates is the shortest possible time interval for which a maximum of one update will occur. So you have registered for at most one update every second, but the actual update may take more that that to occur, and, furthermore, no guarantee is given for that.
From the documentation:
minTime - the minimum time interval for notifications, in milliseconds. This field is only used as a hint to conserve power, and actual time between location updates may be greater or lesser than this value.
Try to set that time interval to 0 and if there are no other problems (although it all seems fine to me), you should start getting the updates "as frequently as possible".