Get location on click of a button with default provider [duplicate] - android

This question already has answers here:
How do I get the current GPS location programmatically in Android?
(21 answers)
Closed 8 years ago.
I need to get the current location using NETWORK_PROVIDER on the click of a button. If network is not available, I want to use GPS_PROVIDER to get location. How can I do this?

this is what i am doing in my case :
MyLocation class :
import android.app.ProgressDialog;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
public class MyLocation {
// Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
AsyncTask<Context, Void, Void> mtask;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
// timer1=new Timer();
// timer1.schedule(new GetLastLocation(), 20000);
mtask= new GetLastLocation().execute();
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
// timer1.cancel();
mtask.cancel(true);
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
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) {
mtask.cancel(true);
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
private Context mContext;
public MyLocation(Context c) { this.mContext = c; }
class GetLastLocation extends AsyncTask<Context, Void, Void>
{
ProgressDialog dialog = new ProgressDialog(mContext);
protected void onPreExecute()
{
dialog.setMessage("Searching....");
dialog.show();
}
protected Void doInBackground(Context... params)
{
Handler mHandler = new Handler(Looper.getMainLooper());
// ...
mHandler.post(new Runnable() {
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
});
// ...
return null;
}
protected void onPostExecute(final Void unused)
{
dialog.dismiss();
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
and the method for button click :
MyLocation myLocation = new MyLocation();
private void locationClick() {
myLocation.getLocation(this, locationResult));
}
public LocationResult locationResult = new LocationResult(){
#Override
public void gotLocation(final Location location){
//Got the location!
});
}
};
I have found this from an older post in stackoverflow when i was looking solution for the similar issue......

You have use this method to check all enable providers
void requestLocationUpdates()
{
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
List<String> enabledProviders = this.locationManager.getProviders(true);
for (String provider:enabledProviders){
Log.i(">>>>>>>", "Requesting location updates from provider " + provider);
this.locationManager.requestLocationUpdates(provider, 10000l, 10, this);
}
}

LocationManager locMgr = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener locListner = new LocationListener() {
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
public void onLocationChanged(Location location) {
// CODE TO READ LOCATION
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
}
};
// ON Click of button do this request.
locMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locListner);
Also you need to add permission in your manifest file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
For more details refer Developer Guide

Related

Disable location updates from GPS

UPDATED QUESTION - STILL NOT WORKING
I've changed the code.
Now, deactivateAlerts and activateAlerts are in the MainActivity.
Now, inside activateAlerts(), I'm instantiating a GPSListener for the GPS Provider:
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
gpsListener = new GPSListener(getApplicationContext());
} else if
Where the GPSListener is this:
public class GPSListener implements LocationListener {
private Context mCtx;
private Location cLoc;
private LocationManager mLocMan;
public GPSListener (Context ctx){
mCtx = ctx;
mLocMan = (LocationManager) mCtx.getSystemService(Context.LOCATION_SERVICE);
mLocMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
public Location getLocation()
{
cLoc = mLocMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
return cLoc;
}
public void stop()
{
mLocMan.removeUpdates(GPSListener.this);
}
#Override
public void onLocationChanged(Location location) {
Log.i("UPDATING", "updating location");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
With the deactiveAlerts() function, I execute the instruction to remove the GPS updates:
if(gpsListener!=null){
gpsListener.stop();
}
But the GPS is not stopping yet =(
What is the problem now?
ORIGINAL QUESTION
The user can activate or deactivate location updates.
If the location updates are activated, it works ok, but when the location updates are deactivated, the GPS is still waiting for updates (and the icon appears on the action bar).
The code is that:
public class Alerts extends Fragment {
MyLocationListener myLocationListener = null;
...
public void activateAlerts() {
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
myLocationListener = new MyLocationListener();
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
Utils.MINIMUM_TIME_BETWEEN_UPDATE,
Utils.MINIMUM_DISTANCECHANGE_FOR_UPDATE,
myLocationListener
);
} else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
Utils.MINIMUM_TIME_BETWEEN_UPDATE,
Utils.MINIMUM_DISTANCECHANGE_FOR_UPDATE,
myLocationListener
);
} else {
locationManager.requestLocationUpdates(
LocationManager.PASSIVE_PROVIDER,
Utils.MINIMUM_TIME_BETWEEN_UPDATE,
Utils.MINIMUM_DISTANCECHANGE_FOR_UPDATE,
myLocationListener
);
}
}
});
...
}
public void deactivateAlerts() {
...
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
if(myLocationListener != null) {
locationManager.removeUpdates(myLocationListener);
myLocationListener = null;
}
...
}
public class MyLocationListener implements android.location.LocationListener {
public void onLocationChanged(Location location) {
Log.i("UPDATING", "updating location");
}
public void onStatusChanged(String s, int i, Bundle b) {
Log.v("LocationListener", "onStatusChanged");
}
public void onProviderDisabled(String s) {
Log.v("LocationListener", "onProviderDisabled");
}
public void onProviderEnabled(String s) {
Log.v("LocationListener", "onProviderEnabled");
}
}
What is the problem?
I've read this posts:
Post1
Post2
Post3
Post4

Got a code snippet for getting Location, don't wanna take Network Location into consideration

I am pretty new to Android, and I took a code snippet from stackoverflow with getting Location. It works perfect, but when network internet is activated, it takes the coordinates from there, and they aren't quite accurate, or at all(sometimes getting 5km+ errors).
I want my location code getting snippet to get only GPS location, but my current knowledge does not allow me to modify it such that i can obtain that.
Here is the code snippet:
package com.fourbox.bocterapp;
/**
* Created by Soulstorm on 10/14/2014.
*/
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 50000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
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) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
Here is how i use it:
MyLocation.LocationResult locationResult = new MyLocation.LocationResult() {
#Override
public void gotLocation(Location location) {
currentUserLatitude = location.getLatitude();
currentUserLongitude = location.getLongitude();
new RemoteDataTask().execute();
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);
Can you please help me to modify my code so my snippet does not get the Network coordinates, only the GPS ones?
Thanks in advance!
Respects.
The following two lines in the GetLastLocation class is where you subscribe to location updates via the network location provider.
Simply remove these two lines of code to no longer receive updates from the the network location provider.
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
Note, location updates from the GPS can take longer than from the network. So if speed is an issue, an alternative approach would be to still use the network location updates, but filter on the accuracy value. This would look something like this:
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
if (location.getAccuracy() > THRESHOLD) {
return;
}
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};

Making my activity wait until i receive my GPS coordinates. (Android, AsyncTask)

I want to make my activity wait unti the GPS locates the user, and only then move to "new RemoteDataTask().execute();". Is there any way i can do that? I tried with do () while, Thread.sleep, etc. They work, but slow down gravely my coordinates receiving process. Is there a more efficient way to do that?
Here is my class where is use the Location Service:
package com.fourbox.bocterapp;
//declarations
public class RecentSightings extends Activity {
//more declarations
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(com.fourbox.bocterapp.R.layout.recent_sightings_design);
if (getIntent().hasExtra("currentUserLatitude")) {
currentUserLatitude = getIntent().getDoubleExtra("currentUserLatitude", 0);
currentUserLongitude = getIntent().getDoubleExtra("currentUserLongitude", 0);
}
locationManager = (LocationManager) RecentSightings.this.getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
if (currentUserLatitude==0) {
MyLocation.LocationResult locationResult = new MyLocation.LocationResult() {
#Override
public void gotLocation(Location location) {
currentUserLatitude = location.getLatitude();
currentUserLongitude = location.getLongitude();
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);
Toast.makeText(this, "Please wait until we get your coordinates!", Toast.LENGTH_SHORT).show();
}
} else {
showGPSDisabledAlertToUser();
}
new RemoteDataTask().execute();
}
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(RecentSightings.this);
// Set progressdialog title
mProgressDialog.setTitle("Loading recent sightings");
// Set progressdialog message
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("AlertsClass");
query.orderByDescending("_created_at");
try {
ob = query.find();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(com.fourbox.bocterapp.R.id.alertListView);
Location currentUserLocation = new Location("currentUserLocation");
currentUserLocation.setLatitude(currentUserLatitude);
currentUserLocation.setLongitude(currentUserLongitude);
getDataForListView();
CustomAdapter adapter = new CustomAdapter(RecentSightings.this, com.fourbox.bocterapp.R.layout.list_item, alertsList, currentUserLocation);
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
// Capture button clicks on ListView items
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Send single item click data to SingleItemView Class
Intent i = new Intent(RecentSightings.this,
AlertViewOnMap.class);
// Pass data "name" followed by the position
i.putExtra("coordinatesLatitude", alertsList.get(position).getCoordinates().getLatitude());
i.putExtra("coordinatesLongitude", alertsList.get(position).getCoordinates().getLongitude());
i.putExtra("description", alertsList.get(position).getDescription());
i.putExtra("busNumber", alertsList.get(position).getBusNumber());
i.putExtra("createdAt", alertsList.get(position).getCreatedAt().getTime());
i.putExtra("currentUserLatitude", currentUserLatitude);
i.putExtra("currentUserLongitude", currentUserLongitude);
i.putStringArrayListExtra("busNumberList", busNumberList);
i.putStringArrayListExtra("descriptionList", descriptionList);
i.putStringArrayListExtra("coordinatesLatitudeList", coordinatesLatitudeList);
i.putStringArrayListExtra("coordinatesLongitudeList", coordinatesLongitudeList);
i.putStringArrayListExtra("dateCreatedAtList", dateCreatedAtList);
// Open SingleItemView.java Activity
startActivity(i);
}
});
}
}
Anticipated thanks for the help! Cheers.
Edit #1: Added MyLocation Class:
package com.fourbox.bocterapp;
/**
* Created by Soulstorm on 10/14/2014.
*/
public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 50000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
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) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
Can't you just move the execute call in the gotLocation callback you already have ?
public void gotLocation(Location location) {
currentUserLatitude = location.getLatitude();
currentUserLongitude = location.getLongitude();
new RemoteDataTask().execute();
}
You may need to post the MyLocation class to make sure I'm getting how this works.

Android Location listener in Service does not work until I reactivate WiFi/mobile network

My location listener works normally, collects data without any problem. But sometimes it doesn't collect any data. I have to turn off and restart my location provider at this time. Restarting fixes the problem,however, it's probably not the best thing the user is expected to do.
When I use GPS as provider, there is no problem.
Location listener works in Service. I can't understand the problem. Is it about Android or my code?
Thanks in advance.
You could use new location provider (FusedLocationProvider), which combines info from different location providers, so if your device has any possibility to obtain location, You'll get know it. Of course, You should enable in preferences for your device to use location info by apps.
Check developers.android.com for extended info about this provider.
This is solution working fine for me:
public class FusedLocationListener implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
public interface LocationListener {
public void onReceiveLocation(Location location);
}
private LocationListener mListener;
public static final String TAG = "Fused";
private LocationClient locationClient;
private LocationRequest locationRequest;
protected int minDistanceToUpdate = 1000;
protected int minTimeToUpdate = 10*1000;
protected Context mContext;
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "Connected");
locationRequest = new LocationRequest();
locationRequest.setSmallestDisplacement(1);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30000);
locationRequest.setNumUpdates(1);
locationClient.requestLocationUpdates(locationRequest, this);
}
#Override
public void onDisconnected() {
Log.d(TAG, "Disconnected");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Failed");
}
private static FusedLocationListener instance;
public static synchronized FusedLocationListener getInstance(Context context, LocationListener listener){
if (null==instance) {
instance = new FusedLocationListener(context, listener);
}
return instance;
}
private FusedLocationListener(Context context, LocationListener listener){
mContext = context;
mListener = listener;
}
public void start(){
Log.d(TAG, "Listener started");
locationClient = new LocationClient(mContext,this,this);
locationClient.connect();
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Location received: " + location.getLatitude() + ";" + location.getLongitude());
//notify listener with new location
mListener.onReceiveLocation(location);
}
public void stop() {
locationClient.removeLocationUpdates(this);
}
}
Usage:
public class MyActivity extends Activity implements FusedLocationListener.LocationListener {
#Override
public void onCreate(Bundle savedInstanceState) {
FusedLocationListener locationListener FusedLocationListener.getInstance(getApplicationContext(), this);
locationListener.start();
}
#Override
public void onReceiveLocation(Location location) {
//handle location here
}
}
Why dont you use both *GPS_PROVIDER* and *NETWORK_PROVIDER* ? I tried this and it was working fine.
Does this error occur while testing on other devices also or only your device ?
You can create detect both of these for me I've used both GPS_PROVIDER and NETWORK_PROVIDER if It can't detect any GPS after 20seconds it will try to use NETWORK provider
///First create MYlocation class
public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 20000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
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) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public void cancelTimer()
{ timer1.cancel();
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
/Into your main class you can use it like this which I implies to a webview
public class Main extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView=(WebView)findViewById(R.id.webview);
final String string_loc = getIntent().getExtras().getString("nearest");
LocationResult locationResult = new LocationResult(){
#Override
public void gotLocation(Location location) {
passLat=Double.toString(location.getLatitude());
passLong=Double.toString(location.getLongitude());
maps="http://maps.google.com/maps?q="+string_loc+"+loc:"+passLat+","+passLong+"&hq=hospital&t=m&z=12";
mWebView.loadUrl(maps);
}
};
myLocation.getLocation(this, locationResult);
}
}
}
//Hoping this would help you
Using the network provider requires internet connection to work. It collects some information from the cell and wifi hotspots. It then queries a backend server which looks up its database and gives an approximate location. The device can prefetch some location info so you don't need constant internet connection but when the device moves out of the prefetch location, it will need internet connection again.
This might be your problem that you loose internet connection sometime (wifi going to sleep) and restarting the provider gets it to reconnect to the internet again. Again this is at best a guess on my part :)

Access LocationManager/ LocationListener from class

I'm kinda lost here: In my main activity, I register a LocationManager and connect it to a LocationListener to use myLocation.getLatitude() and such.
Now I need to use the Location- methods from another class.
I can't use those object from another class because I cant intantiate the main activity.
I can't use getters to pass the L.Manager or L.Listener around, because those are non- static again.
So, in general, how do i access objects that I created in the main activity?
Any hints on how to organize this better? Is the LocationListener class within the main activity class a stupid thing to do in general?
public class URNavActivity extends Activity
{
public LocationManager mlocManager;
public LocationListener mlocListener;
...
}
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext());
actVar=this;
initGraph();
setMap();
gpsEnable();
initMyLocation();
getItems();
initOverlay();
}
public void gpsEnable ()
{
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
public class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
myMap.getController().setCenter(new GeoPoint(lati, longi));
}
First and foremost your LocationListener should not be part of an activity. Activities have a clearly defined lifecycle and can come into being, and be destroyed, by the Android framework on an as-needed basis. Therefore the instance variables of your Activity will need to be re-initialised in your activity's onResume() method, making them completely unsuitable for long-term storage.
So. Start by creating a sticky service to manage the starting and stopping of location updates. Being sticky means that the service instance hangs around between invocations and therefore you can reliably use instance variables and know that they will retain their values until the service is terminated. This service should also implement the LocationListener interface, and now it can store the Location notified to it when onLocationChanged is invoked:
public class LocationService extends Service implements LocationListener {
private LocationManager locationManager;
private Location location;
#Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
Logging.i(CLAZZ, "onHandleIntent", "invoked");
if (intent.getAction().equals("startListening")) {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
else {
if (intent.getAction().equals("stopListening")) {
locationManager.removeUpdates(this);
locationManager = null;
}
}
return START_STICKY;
}
#Override
public IBinder onBind(final Intent intent) {
return null;
}
public void onLocationChanged(final Location location) {
this.location = location;
// TODO this is where you'd do something like context.sendBroadcast()
}
public void onProviderDisabled(final String provider) {
}
public void onProviderEnabled(final String provider) {
}
public void onStatusChanged(final String arg0, final int arg1, final Bundle arg2) {
}
}
Now you have a service you can start and stop the location updates as you need them. This also allows you to continue to receive and process location changes even when your application is not in the foreground, if that is what you want.
You now have two choices on how to make that Location information available: Use context.sendBroadcast() to propagate the new Location to (for example) an activity, or use the bound service approach to allow other classes to invoke the exposed API and obtain the Location. See http://developer.android.com/guide/topics/fundamentals/bound-services.html for more details on creating a bound service.
Note that there are many other aspects to listening for location updates that I have not included here, for the sake of clarity.
I would offer two elegant ways to access your object from anywhere:
use a Singleton design pattern
use ProjectApp class. This class can be accessed from any activity simply by calling getApplication().
ProjectApp app = (ProjectApp)getApplication();
I used a combination of the two:
public class MyApp extends Application {
private MyLocation mMyLocation;
#Override
public void onCreate() {
super.onCreate();
mMyLocation = new MyLocation();
mMyLocation.getLocation(this, GlobalData.getInstance(), true);
}
}
You can see that GlobalData is a singleton class that implements LocationResult interface, meaning that it will send the updated location to this object.
When I need to get the updated location, I take it from GlobalData.
Here is MyLocation class implementation (I used some code from here and made some changes:
package com.pinhassi.android.utilslib;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class MyLocation {
private Timer timer1;
private LocationManager lm;
private LocationResult locationResult;
private boolean gps_enabled=false;
private boolean network_enabled=false;
private boolean mContinuesUpdates;
private int decimalAccuracy;
/**
* Class constructor
*/
public MyLocation(){
decimalAccuracy = 0;
}
public boolean getLocation(Context context, LocationResult result, boolean continuesUpdates)
{
mContinuesUpdates = continuesUpdates;
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 20000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(getDecimalAccurated(location));
if (!mContinuesUpdates)
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
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) {
timer1.cancel();
locationResult.gotLocation(getDecimalAccurated(location));
if (!mContinuesUpdates)
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(getDecimalAccurated(gps_loc));
else
locationResult.gotLocation(getDecimalAccurated(net_loc));
return;
}
if(gps_loc!=null){
locationResult.gotLocation(getDecimalAccurated(gps_loc));
return;
}
if(net_loc!=null){
locationResult.gotLocation(getDecimalAccurated(net_loc));
return;
}
locationResult.gotLocation(null);
}
}
/**
* called when the GPS returns a location.
* can be called multiple times as the location is updated
*/
public interface LocationResult {
public void gotLocation(Location location);
}
/**
* sets location result accuracy
* #param n number of places after the point. negative value or 0 means not set.
*/
public void setDecimalAccuracy(int n)
{
this.decimalAccuracy = n;
}
private Location getDecimalAccurated(Location location) {
if (decimalAccuracy > 0){
double accuracy = Math.pow(10, this.decimalAccuracy);
int ix;
ix = (int)(location.getLatitude() * accuracy);
location.setLatitude(((double)ix)/accuracy);
ix = (int)(location.getLongitude() * accuracy);
location.setLongitude(((double)ix)/accuracy);
}
return location;
}
}
I'll talk in general since I had the same issue:
How to manage the LocationListener and lit this listener access the activity ..
This was my try :
The Listener :
public class MyLocationListener implements LocationListener{
ProgressDialog dialog;
LocationManager locManager;
Context context;
public MyLocationListener (Context context,ProgressDialog dialog){
this.context = context;
this.dialog = dialog;
}
public void startSearch() {
locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// If the network provider works run it , else try GPS provider
// TODO : what happens if GPS and Network providers are not suuported ??
if(!locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) )
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
0, this);
else
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0,
0, this);
dialog = new ProgressDialog(context);
dialog.setTitle("");
dialog.setMessage(context.getString(R.string.pleaseWait));
dialog.setButton(context.getString(R.string.cancel), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
locManager.removeUpdates(MyLocationListener .this);
dialog.dismiss();
return;
}
});
dialog.show();
}
// Location Listener implementation
// read Android doc for more info
// this methods is triggered when new location ( latitiude and longitude ) is found by the system
private void updateWithNewLocation(Location location) {
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
//THIS IS MY ACTIVITY
MainActivity mainActivity = (MainActivity) context;
mainActivity.init();
} else {
//this.setSummary( "No location found" );
}
// remove the listener , we don't need it anymore
locManager.removeUpdates(this);
dialog.hide();
}
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
init the listener in the MainActivity like this :
ProgressDialog dialog;
.
.
.
new MyLocationListener (this, dialog).startSearch();
I don't know if that help ? but that was my solution ...

Categories

Resources