I have an activity which uses onLocationChanged method and upon performing a parse query it makes a toast. It works fine. However, when I go to another activity (it's a maps activity), if I change the coordinates (I'm using an emulator) the toast pops up. I would like to know why the onLocationChanged method is still running. I thought it may be due to context, but I specified the activity in the context field.
locationManager = (LocationManager) DriverChoicesActivity.this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(final Location location) {
final ParseGeoPoint parseGeoPoint = new ParseGeoPoint(location.getLatitude(), location.getLongitude());
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("username", ParseUser.getCurrentUser().getUsername());
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> objects, ParseException e) {
if (e == null && objects.size() > 0) {
for (ParseObject object : objects) {
object.put("driverLocation", parseGeoPoint);
object.saveInBackground();
Toast.makeText(DriverChoicesActivity.this, "User found", Toast.LENGTH_SHORT).show();
}
}
}
});
updateRequestList(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
All that is within onCreate of the original activity (DriverChoicesActivity.class). The other activity (DriverMapActivity.class) has no code in it apart from getting the intent from this activity to collect some latitude and longitude points. Here is the code which makes the intent (also within onCreate)
requestListView.setAdapter(arrayAdapter);
requestListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (requestLatitude.size() > position && requestLongitude.size() > position) {
if (Build.VERSION.SDK_INT < 23 || ContextCompat.checkSelfPermission(DriverChoicesActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Location getLastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (getLastKnownLocation != null) {
Intent intent = new Intent(getApplicationContext(), DriverMapActivity.class);
intent.putExtra("requestLatitude", requestLatitude.get(position));
intent.putExtra("requestLongitude", requestLongitude.get(position));
intent.putExtra("driverLatitude", getLastKnownLocation.getLatitude());
intent.putExtra("driverLongitude", getLastKnownLocation.getLongitude());
startActivity(intent);
}
}
}
}
});
I assume my problem is with context somehow. If someone could be kind enough to explain.
Thank you
You must add:
locationManager.removeUpdates(listener);
Before move to next Activity.
and
LocationManager locationManager;
LocationListener locationListener;
on the top, under class declaraction
Related
I'm doing a Udacity Android Basics course and am trying to change my app to use a Loader rather than AsyncTask. My app uses a locationListener to generate a custom URL that is then passed to the loader, loader calls ChargePointLoader class which initates the HTTP request and returns a list of chargePoints, which should populate the adapter once loaded.
However nothing appears on my screen. Do I have the order of my loader wrong or is the locationListener interfering with the loader? Thanks for any help
Here is a link to the old Async Project: https://github.com/Kovah101/ChargeMyCarBareBones/blob/master/app/src/main/java/com/example/android/chargemycar/MainActivity.java
Here is my Main activity
public class MainActivity extends AppCompatActivity implements LoaderCallbacks<List<ChargePoint>> {
public static final String LOG_TAG = MainActivity.class.getName();
public static double myLat;
public static double myLong;
private static String ChargePoint_REQUEST_URL = "http://chargepoints.dft.gov.uk/api/retrieve/registry/postcode/SW15+5QS/dist/7/format/json/limit/10";
private ChargePointAdapter adapter;
private LocationManager locationManager;
private LocationListener locationListener;
private static final int CHARGEPOINT_LOADER_ID = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find a reference to the {#link ListView} in the layout
final ListView chargePointListView = (ListView) findViewById(R.id.list);
// Create a ChargingPointAdapter, whose data source is a list of ChargePoints, which creates listview items for each item
adapter = new ChargePointAdapter(this, new ArrayList<ChargePoint>());
//possible error with order of loaders or inside listener
final LoaderManager loaderManager = getLoaderManager();
locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//set lat & long variables
myLat = location.getLatitude();
myLong = location.getLongitude();
String myLatString = Double.toString(myLat);
String myLongString = Double.toString(myLong);
//test with toast
Context context = getApplicationContext();
CharSequence text = " my latitude=" +myLatString +"\nmy longitude=" +myLongString ;
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
//create request URL using live location
ChargePoint_REQUEST_URL = "http://chargepoints.dft.gov.uk/api/retrieve/registry/lat/" +myLat + "/long/" +myLong +"/dist/10/format/json/limit/10";
// Set the adapter on the {#link ListView}
// so the list can be populated in the user interface
chargePointListView.setAdapter(adapter);
loaderManager.initLoader(CHARGEPOINT_LOADER_ID, null, MainActivity.this );
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}else{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 100, locationListener);
//time in milliseconds
//distance in meters
}
// On click take to maps
chargePointListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String myLatString = Double.toString(myLat);
String myLongString = Double.toString(myLong);
ChargePoint currentChargePoint = (ChargePoint) chargePointListView.getItemAtPosition(position);
double destinationLatitude = currentChargePoint.getLatitude();
double destinationLongitude = currentChargePoint.getLongitude();
String destLatString = Double.toString(destinationLatitude);
String destLongString = Double.toString(destinationLongitude);
//create uri for map intent
String url = "http://maps.google.com/maps?saddr="+myLatString+","+myLongString+"&daddr="+destLatString+","+destLongString+"&travelmode=driving";
Intent mapIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(url));
mapIntent.setPackage("com.google.android.apps.maps");
if (mapIntent.resolveActivity(getPackageManager()) != null) {
startActivity(mapIntent);
}
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 25, locationListener);
//time in ms, distance in meters
}
}
}
#Override
public Loader<List<ChargePoint>> onCreateLoader(int i, Bundle bundle) {
return new ChargePointLoader(this, ChargePoint_REQUEST_URL);
}
#Override
public void onLoadFinished(Loader<List<ChargePoint>> loader, List<ChargePoint> chargePoints) {
// Clear the adapter of previous data
adapter.clear();
//check for null charge point list, return early if that is the case, if there is a valid list then add to the adapter
if (chargePoints != null && !chargePoints.isEmpty()){
adapter.addAll(chargePoints);
}
}
#Override
public void onLoaderReset(Loader<List<ChargePoint>> loader) {
// TODO: Loader reset, so we can clear out our existing data.
adapter.clear();
}
}
Loaders are now deprecated, use Android Architecture Components (LiveData and ViewModel) with your old AsyncTask. It works more efficiently, faster and cleaner than Loaders. It also makes your AsyncTask to be lifecycle aware. Lifecycle aware in a sense that your network request will not be made again after once no matter how many times you call onCreate() because it automatically caches downloaded data. Configuration changes won't affect your app. For more information on using AsyncTask with LiveData and ViewModel, visit https://medium.com/androiddevelopers/lifecycle-aware-data-loading-with-android-architecture-components-f95484159de4
I have an activity in which I have a text view where I want to display the distance between the user's current location and a specific address. I have the Latitude and Logitude of the address but my issue is getting the user's location. My target is when the activity is created that's when I want to get his location' without pressing any button. I have tried multiple ways: getLastKnownLocation, onLocation changed etc, but the value returned is always null.
It's important to note that I am running the app on an emulator.
Sample code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_business_list);
Bundle bundleUser = getIntent().getExtras();
final String owneruser = bundleUser.getString("username");
Bundle bundleType = getIntent().getExtras();
String type = bundleType.getString("type");
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
final TextView t = (TextView) findViewById(R.id.textView2);
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
t.append("\n " + location.getLongitude() + " " + location.getLatitude());
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(i);
}
};
final Location userLocation = new Location("");
userLocation.setLatitude(latitude);
userLocation.setLongitude(longitude);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case 10:
update();
break;
default:
break;
}
}
void update(){
// first check for permissions
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.INTERNET}
,10);
}
}
else {
locationManager.requestLocationUpdates("gps", 5000, 0, listener);
}
}
implement your activity to LocationListener :
public class MyActivity extends AppCompatActivity implements LocationListener {
private Location userLocation = new Location("");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
}
#Override
public void onLocationChanged(Location location) {
if(location != null){
userLocation.setLatitude(location.getLatitude());
userLocation.setLongitude(location.getLongitude());
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
TRY this to grant permission:
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an expanation to the user *asynchronously* -- don't block this thread waiting for the user's response! After the user sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, RC_ACCESS_FINE_LOCATION);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an app-defined int constant. The callback method gets the result of the request.
}
}
and add this in your manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
The thing is that I'm trying on the emulator, and it works but only once I press the "send location to device" on the emulator but before that I don't have the chance to get the location....How do I get the location for the first time using this service?. I don't have a real device right know and the emulator is my only way of testing this for now.....I tried to send a 0,0 at first to see if that would trigger a location update but it's not working as well......any ideas?
#SuppressWarnings("MissingPermission")
public class GPSService extends Service {
private LocationListener listener;
private LocationManager locationManager;
private String lastKnownLatitude;
private String lastKnownLongitude;
private Boolean isFirstTime=true;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
broadcastLocation("0","0");
listener= new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//To transfer the data to the main activity I use broadcast receiver in the main activity, using an intent filter location_update
Intent intentSendLocationMainActivity = new Intent("location_update");
lastKnownLatitude=""+location.getLatitude();
lastKnownLongitude=""+location.getLongitude();
Log.d("LOCATION-UPDATE",lastKnownLatitude+" long:"+lastKnownLongitude);
broadcastLocation(lastKnownLatitude,lastKnownLongitude);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
Log.d("GPS-Stat-Changed",s);
}
#Override
public void onProviderEnabled(String s) {
Log.d("GPS-Provider-Enabled",s);
}
#Override
public void onProviderDisabled(String s) {
Intent activateGPSIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activateGPSIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activateGPSIntent);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
//noinspection MissingPermission, listen for updates every 3 seconds
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,0,listener);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
Log.d("LAST_LAT_AND_LONG",lastKnownLatitude+" "+lastKnownLongitude);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("ClearFromRecentService", "Service Destroyed, Removing update location listener");
//unregistering the listener
/*if(locationManager != null){
locationManager.removeUpdates(listener);
}*/
}
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
//here you can call a background network request to post you location to server when app is killed
Toast.makeText(getApplicationContext(), "I'm still getting user coordinates", Toast.LENGTH_LONG).show();
//stopSelf(); //call this method to stop the service
}
public void broadcastLocation(String latitude,String longitude){
Intent intentSendLocationMainActivity = new Intent("location_update");
intentSendLocationMainActivity.putExtra("latitude",latitude);
intentSendLocationMainActivity.putExtra("longitude",longitude);
//I need to differentiate here if the app is killed or not to send the location to main activity or to a server
sendBroadcast(intentSendLocationMainActivity);
}
}
EDIT: This is the complete service working. For the first time it gets the coordinates with the getLastKnownLocation() and the on sucesive times with the listener onLocationChanged()
#SuppressWarnings("MissingPermission")
public class GPSService extends Service {
private LocationListener listener;
private LocationManager locationManager;
private String lastKnownLatitude;
private String lastKnownLongitude;
private Boolean isFirstTime=true;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
listener= new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//To transfer the data to the main activity I use broadcast receiver in the main activity, using an intent filter location_update
Intent intentSendLocationMainActivity = new Intent("location_update");
lastKnownLatitude=""+location.getLatitude();
lastKnownLongitude=""+location.getLongitude();
Log.d("LOCATION-UPDATE",lastKnownLatitude+" long:"+lastKnownLongitude);
broadcastLocation(lastKnownLatitude,lastKnownLongitude);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
Log.d("GPS-Stat-Changed",s);
}
#Override
public void onProviderEnabled(String s) {
Log.d("GPS-Provider-Enabled",s);
}
#Override
public void onProviderDisabled(String s) {
Intent activateGPSIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activateGPSIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activateGPSIntent);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
//noinspection MissingPermission, listen for updates every 3 seconds
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,0,listener);
Map<String, String> coordinates=getLastKnownLocation(locationManager);
broadcastLocation(coordinates.get("latitude"),coordinates.get("longitude"));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
Log.d("LAST_LAT_AND_LONG",lastKnownLatitude+" "+lastKnownLongitude);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("ClearFromRecentService", "Service Destroyed, Removing update location listener");
//unregistering the listener
/*if(locationManager != null){
locationManager.removeUpdates(listener);
}*/
}
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
//here you can call a background network request to post you location to server when app is killed
Toast.makeText(getApplicationContext(), "I'm still getting user coordinates", Toast.LENGTH_LONG).show();
//stopSelf(); //call this method to stop the service
}
private void broadcastLocation(String latitude,String longitude){
Intent intentSendLocationMainActivity = new Intent("location_update");
intentSendLocationMainActivity.putExtra("latitude",latitude);
intentSendLocationMainActivity.putExtra("longitude",longitude);
//I need to differentiate here if the app is killed or not to send the location to main activity or to a server
sendBroadcast(intentSendLocationMainActivity);
}
private Map<String, String> getLastKnownLocation(LocationManager lm){
Location lastKnownLocation=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
String ll=""+lastKnownLocation.getLatitude();
Map<String, String> coordinates = new HashMap<String, String>();
// Check everytime this value, it may be null
if(lastKnownLocation != null){
coordinates.put("latitude",""+lastKnownLocation.getLatitude());
coordinates.put("longitude",""+lastKnownLocation.getLongitude());
}else{
coordinates.put("latitude","0");
coordinates.put("longitude","0");
}
return coordinates;
}
}
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
Location lastKnownLocation = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// Check everytime this value, it may be null
if(lastKnownLocation != null){
double latitude = lastKnownLocation.getLatitude();
double longitude = lastKnownLocation.getLongitude();
// Use values as you wish
}
broadcastLocation("0","0");
....
}
I am writting code for getting current location (latitude and longitude) of my phone. I display a toast whether Network Location service is provided by the phone or not. This toast doesn't show up ever. The other question is, for getting current location using Network_location, will the app use phone's gprs/internet or not?
I have created the instance of this class in the main activity and then get data using Latitude and Longitude variables of this class, in another class which extends broadcast reciever .
public class GpsClass extends Activity{
public static String Latitude="";
public static String Longitude="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener listener = new LocationListener() { // anonymous class
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location currentLocation) {
double lat= currentLocation.getLatitude();
Latitude = Double.toString(lat);
double longt= currentLocation.getLongitude();
Longitude = Double.toString(longt);
}
};
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
if(manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
Toast.makeText(getApplicationContext(), "Network enabled", 0).show();
}
else
Toast.makeText(getApplicationContext(), "Network not enabled", 0).show();
}
}
Is there anything I am doing wrong?
Regards
I think the problem is that you are passing 0 for duration i.e. last parameter of makeText() method.
Try passing Toast.LENGTH_SHORT or Toast.LENGTH_LONG.
if(manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
Toast.makeText(getApplicationContext(), "Network enabled", Toast.LENGTH_LONG).show();
}
else
Toast.makeText(getApplicationContext(), "Network not enabled", Toast.LENGTH_LONG).show();
This can help you to get answer to your first question.
The answer to your second question is - No, the app will not use phone's gprs/internet for getting location through network provider.
The problem is setting 0 for duration.
This is a sample example:
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
currentLocation = new GeoPoint(location.getLatitude(), location.getLongitude());
// Set Toast Here To Diplay location
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//10000 means request update every 10 sec
//10 tell listener that if location change more than 10m then run locationChanged method
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10, locationListener);
} else {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 10, locationListener);
}
Is there a way to access the GPS once instead of having a looper that constantly checks for location updates?
In my scenario all I'm interested in is finding the current co-ordinates and not a continuous connection with the GPS satellite. Does anyone have any ideas how this can be done? Thanks in advance.
Dont use the getLastKnownLocation because that could be returning null or old data.
This code Only fetches the location once a button is pressed and not every time. People use to leave the location listener listen in every instance and that kills the battery life so Use the code snippet I have posted by doing lots of research:
// get the text view and buttons from the xml layout
Button button = (Button) findViewById(R.id.btnGetLocation);
final TextView latitude = (TextView) findViewById(R.id.textview4);
final TextView longitude = (TextView) findViewById(R.id.textview5);
final LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
mlocation = location;
Log.d("Location Changes", location.toString());
latitude.setText(String.valueOf(location.getLatitude()));
longitude.setText(String.valueOf(location.getLongitude()));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Status Changed", String.valueOf(status));
}
#Override
public void onProviderEnabled(String provider) {
Log.d("Provider Enabled", provider);
}
#Override
public void onProviderDisabled(String provider) {
Log.d("Provider Disabled", provider);
}
};
// Now first make a criteria with your requirements
// this is done to save the battery life of the device
// there are various other other criteria you can search for..
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setSpeedRequired(false);
criteria.setCostAllowed(true);
criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH);
// Now create a location manager
final LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
// This is the Best And IMPORTANT part
final Looper looper = null;
// Now whenever the button is clicked fetch the location one time
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
locationManager.requestSingleUpdate(criteria, locationListener, looper);
}
});
First check if the last know location is recent. If not, I believe you must to set up onLocationChanged listener, but once you get your first valid location you can always stop the stream of updates.
Addition
public class Example extends Activity implements LocationListener {
LocationManager mLocationManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null && location.getTime() > Calendar.getInstance().getTimeInMillis() - 2 * 60 * 1000) {
// Do something with the recent location fix
// otherwise wait for the update below
}
else {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
}
public void onLocationChanged(Location location) {
if (location != null) {
Log.v("Location Changed", location.getLatitude() + " and " + location.getLongitude());
mLocationManager.removeUpdates(this);
}
}
// Required functions
public void onProviderDisabled(String arg0) {}
public void onProviderEnabled(String arg0) {}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
}