I wonder if anyone can help, because I'm completely confused... I've attached all my code. I've set up a Background service that reports it's location to an XMPP server, to record the current lat/lng of our devices. Everything works lovely and I've brought one of our devices home with me tonight, to map my journey. However, when RDP'ing into the office, I've found out that the lat/lng being reported to HQ every minute is in fact identical to that of when the device was sat on my desk.
I've disabled Wifi on the device thinking that network provider and wifi may be conflicting, but I'm seeing no change.
If anyone can help I'd really appreciate it. Because I can't see what I'm doing wrong. I've checked google and various geolocation examples and as far as I can see, my code should be fine.
Many thanks.
package com.goosesys.gooselib.GeoLocation;
/*
* GeoLocation Class
* GooseLib
*
* Used to access coarse and fine geo-location metrics based on the devices' last known location
*
* PERMISSIONS REQUIRED:
* INTERNET, ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION
*/
import com.goosesys.gooselib.Logging;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class GeoLocation implements LocationListener
{
private LocationManager locationManager = null;
private String provider = "";
#SuppressWarnings("unused")
private double latitude = 0;
#SuppressWarnings("unused")
private double longitude = 0;
#SuppressWarnings("unused")
private Context context = null;
public GeoLocation(Context context)
{
// used to add dialog prompts to the main activity
this.context = context;
locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
if (location != null)
{
Logging.Info("GooseLib", "GeoLocation - provider [" + provider + "] has been selected");
onLocationChanged(location);
}
else
{
locationManager = getLocationUpdates();
Logging.Warning("GooseLib", "GeoLocation - Location not available");
}
}
/*
* Returns the location manager as an object after calling for location updates
*/
public LocationManager getLocationUpdates()
{
locationManager.requestLocationUpdates(provider, 100, 1, this);
return locationManager;
}
/*
* return the latitude of the current devices' location - last known location
*/
public double getLatitude()
{
double lat = 0;
try
{
lat = locationManager.getLastKnownLocation(provider).getLatitude();
}
catch(NullPointerException e)
{
e.printStackTrace();
}
return lat;
}
/*
* returns the longitude of the current devices' location - last known location
*/
public double getLongitude()
{
double lng = 0;
try
{
lng = locationManager.getLastKnownLocation(provider).getLongitude();
}
catch(NullPointerException e)
{
e.printStackTrace();
}
return lng;
}
#Override
public void onLocationChanged(Location location)
{
this.latitude = location.getLatitude();
this.longitude = location.getLongitude();
}
#Override
public void onProviderDisabled(String arg0)
{
Logging.Warning("GooseLib", "GeoLocation - Provider Disabled [" + provider + "]");
}
#Override
public void onProviderEnabled(String arg0)
{
Logging.Info("GooseLib", "GeoLocation - Provider Enabled [" + provider + "]");
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2)
{
// We don't need to worry about this method - just yet
}
}
And my Background Service for Geo posting to XMPP.
package com.goosesys.dta_pta_test;
import org.jivesoftware.smack.packet.Message;
import android.app.IntentService;
import android.content.Intent;
import com.google.gson.Gson;
import com.goosesys.gooselib.GeoLocation.GeoLocation;
import com.goosesys.gooselib.Transactions.Geo;
import com.goosesys.gooselib.Transactions.MessageType;
import com.goosesys.gooselib.Transactions.XMPPTransaction;
import com.goosesys.gooselib.Utilities.AppSettings;
import com.goosesys.gooselib.Utilities.Utility;
public class BGGeoProc extends IntentService
{
public BGGeoProc()
{
super("BGGeoProc");
}
public BGGeoProc(String name)
{
super("BGGeoProc");
}
public void updateLocation()
{
GeoLocation gl = new GeoLocation(getApplicationContext());
double lng = gl.getLongitude();
double lat = gl.getLatitude();
MessageType mt = new MessageType(MessageType.Type.GEO);
Geo g = new Geo(lng, lat);
XMPPTransaction<Object> trans = new XMPPTransaction<Object>(mt, g);
Message m = new Message();
m.setTo(AppSettings.BOT_NAME);
m.setFrom(Utility.getAndroidID(getApplicationContext()));
m.setBody(new Gson().toJson(trans));
Intent s = new Intent(getApplicationContext(), XMPPIntentService.class);
s.putExtra(XMPPIntentService.MESSAGEDATA, new Gson().toJson(m));
startService(s);
}
#Override
protected void onHandleIntent(Intent intent)
{
// Worker thread area //
updateLocation();
}
}
And how I originally start the service (in 1 minute intervals) from the Main Activity
private void startGeoLocationSender()
{
// do some work here
Calendar cal = Calendar.getInstance();
Intent i = new Intent(this, BGGeoProc.class);
PendingIntent pintent = PendingIntent.getService(this, 0, i, 0);
Logging.Info(AppSettings.APP_TAG, "Setting Alarm Manager for BGGeoProc");
// create an alarm manager to hook into system wide calendar
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
AppSettings.COLLECTOR_PROC_1_MINS, pintent);
}
Permissions
<!-- PERMISSION ACCESS -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES" />
It looks like you weren't actually getting any location updated so when you call getLastKnownLocation() it's giving you the last location it knows about which is your desk. Make sure that you have ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permissions and also make sure that the GPS is enabled in the device settings.
Related
I am writhing now simple weather program. I use weather Api and must send location of phone to get weather data. As you understand I don't need precise location, so no need for GPS, noneed for ACCESS_FINE_LOCATION. What I need is - to get my location from NETWORK_PROVIDER. But here starts the problem.
At first I tried to use LocationManager and LocationListener. I enabled my WiFi and location in phone settings. Important thing that I want my application work indoor, so that no need for walking to change coordinates and LocationManager will respond. At first I check last known location.
Location location = mLocationManager.getLastKnownLocation(LOCATION_PROVIDER);
Actually, often it does not work. So I get null as location. Especiall when you turn off location in smartphone settings and after a few minutes turn it on.
OKAY, you don't have lastKnownLocation, then lets get it us. I use requestLocationUpdates() to get current location:
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, mLocationListener);
Now the magic begins... Sometime (one time in several hours OR several times in a minute) the requestLocationUpdates() works. But most of time it does not react. After many searches in internet I found Google Api, in particular FusedLocationProviderClient class. But again same story happens. But now I could understand that requestLocationUpdates() is not called.
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null);
I decided to put a button to see does it sends any requestLocationUpdates, but when I click button I have error.
587-673/? E/ANDR-PERF-MPCTL: Invalid profile no. 0, total profiles 0 only
To Summarize, my app simply dont send requestLocationUpdates. And I need just approximate location of my device to get city name, so no need for GPS. Please help me to solve this problem. Thanks.
You can use this class to get Current or Last Known Location if current location is currently not available.
initialize activity in your Manifest.xml
inside application tag
<activity android:name=".LocationFinder"></activity>
start this activity by calling
startActivity(new Intent(getApplicationContext(), LocationFinder.class));
finish();
Now, you can get Location in any other activity by just calling -> LocationFinder.finalAddress
Location and Internet permissions required
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
LocationFinder.java
import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
#SuppressLint("MissingPermission")
public class LocationFinder extends AppCompatActivity implements LocationListener {
private LocationManager locationManager;
private String provider;
public static String finalAddress;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLoc();
}
public void getLoc() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
if (location == null) {
location = getLastKnownLocation();
}
if (location != null) {
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
} else {
Toast.makeText(this, "Location not available...", Toast.LENGTH_SHORT).show();
}
}
private Location getLastKnownLocation() {
List<String> providers = locationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
#SuppressLint("MissingPermission")
Location l = locationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null
|| l.getAccuracy() < bestLocation.getAccuracy()) {
bestLocation = l;
}
}
if (bestLocation == null) {
return null;
}
return bestLocation;
}
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
//You had this as int. It is advised to have Lat/Loing as double.
double lat = location.getLatitude();
double lng = location.getLongitude();
Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
StringBuilder builder = new StringBuilder();
try {
List<Address> address = geoCoder.getFromLocation(lat, lng, 1);
int maxLines = address.get(0).getMaxAddressLineIndex()+1;
for (int i=0; i<maxLines; i++) {
String addressStr = address.get(0).getAddressLine(i);
builder.append(addressStr);
builder.append(" ");
}
finalAddress = builder.toString(); //This is the complete address.
} catch (IOException | NullPointerException e) {
// Handle IOException
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
}
After getting complete address you can use split method to get country name etc
am trying to create a class that will be used in acquiring the users Location. this class will be utilized by an IntentService in the background.
is there a way to do this without extending Activity or FragmentActivity
in my class.
the code so far looks like below.
import android.app.IntentService;
import android.content.Context;
import static android.content.Context.LOCATION_SERVICE;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
public class LocateMe {
// set loc Listener
LocationManager locationManager;
String update_locid, provider;
double mLon, mLat;
Float accuracy;
int count = 0;
Criteria criteria;
Context context;
IntentService is;
onLocationGot mCallback;
public LocateMe(onLocationGot ints){
is = (IntentService) ints;
// This makes sure that the container service has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (onLocationGot) ints;
} catch (ClassCastException e) {
throw new ClassCastException(ints.toString()
+ " must implement LocateMe.onLocationGot");
}
}
private LocationListener mLocationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Getting latitude of the current myLocation
double latitude = location.getLatitude();
// Getting longitude of the current myLocation
double longitude = location.getLongitude();
// getting accuracy
accuracy = location.getAccuracy();
// Setting latitude and longitude to be used in the TextView
mLat = latitude;
mLon = longitude;
if (count > 5) {
locationManager.removeUpdates(mLocationListener);
}
count++;
mCallback.foundLocation(mLat, mLon, accuracy);
// finish();
}
public void onProviderDisabled(String provider) {// more work required here
// str = provider;
}
public void onProviderEnabled(String provider) {
// str = provider;
}
public void onStatusChanged(String provider, int status, Bundle extras) {
provider = locationManager.getBestProvider(criteria, true);
}
};
// #Override
// public void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// }
public void getLocation() {
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(is.getBaseContext( ));
// Showing status
if (status != ConnectionResult.SUCCESS) { // Google Play Services are not available
// int requestCode = 10;
// Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
// dialog.show();
} else {
// Getting LocationManager object from System Service LOCATION_SERVICE
locationManager = (LocationManager) is.getSystemService(LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
//criteria.setPowerRequirement(Criteria.POWER_LOW);
// Getting the name of the best provider
provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location or on editing saved location
if (provider != null) {
requestLocation(locationManager, provider);
} else {
//start wifi, gps, or tell user to do so
}
}
}
public void requestLocation(LocationManager locationManager, String provider) {
if (provider != null) {
locationManager.requestLocationUpdates(provider, 1000, 0, mLocationListener);
} else {
//tell user what has happened
}
}
public interface onLocationGot {
public void foundLocation(double lat, double lon, Float accuracy);
}
}
I suspect that your question is if you can get LocationService in non-activity class.
If so, then read below.
To access system services you need to call this method. Activity extends Context, so it's able to get system services. IntentService also extends Context, so you can use your constructor param to get location service.
package com.ecsmon.android.core;
import static com.ecsmon.android.constants.Constants.log;
import java.io.IOException;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
#SuppressLint("NewApi")
public class GPSManager {
private double currentLatitude = 0d;
private double currentLongitude = 0d;
private static Context mCtx;
private Location lastLocationBestProvider = null;
private LocationManager mLocationManager;
private GPSListenerImpl mGPSListener;
private com.ecsmon.android.core.LocationListener mOutListener;
private boolean enabled = false;
private GPSListenerImpl mNETListener;
public GPSManager(Context ctx, com.ecsmon.android.core.LocationListener locationListener) {
mCtx = ctx;
mLocationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
mOutListener = locationListener;
}
/**
* Start location updates
*/
public void start() {
log("#### Started tracking");
lastLocationBestProvider = getLastLocationFromBestProvider();
if (lastLocationBestProvider != null) {
currentLatitude = lastLocationBestProvider.getLatitude();
currentLongitude = lastLocationBestProvider.getLongitude();
log("lat" + currentLatitude + " long " + currentLongitude);
} else {
log("last loaction is null");
}
// mGPSListener = new GPSListenerImpl("GPS");
mNETListener = new GPSListenerImpl("NET");
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 1, mNETListener);
// mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, mGPSListener);
}
private class GPSListenerImpl implements LocationListener {
private String name = "";
public GPSListenerImpl(String name) {
log("listener created" + name);
this.name = name;
}
public void onLocationChanged(Location loc) {
log("######### LOCATION CHANGED CALLED!!!!!!!!!!!!!!!!! ##############");
if (loc != null) {
log("######### location changed " + loc.getAccuracy());
currentLatitude = loc.getLatitude();
currentLongitude = loc.getLongitude();
mOutListener.update(currentLongitude, currentLatitude);
} else {
log("location is null");
}
}
public void onProviderDisabled(String provider) {
log("provider disabled > " + name);
}
public void onProviderEnabled(String provider) {
log("provider enabled > " + name);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
log("status changed");
}
}
/**
* Return last location saved in phone or null
*
* #return Location
*/
public Location getLastLocationFromBestProvider() {
if (!enabled) {
return null;
}
try {
LocationManager lm = (LocationManager) mCtx.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
String strLocationProvider = lm.getBestProvider(criteria, true);
Location location = lm.getLastKnownLocation(strLocationProvider);
if (location != null) {
return location;
}
return null;
} catch (Exception e) {
log(e.getMessage());
return null;
}
}
/**
* Returns human readable address from longitude and latitude
*
* #param latitude
* #param longitude
* #return
*/
public String getAddress(Double latitude, Double longitude) {
if (!enabled) {
return null;
}
String m = "";
try {
if (!Geocoder.isPresent()) {
return null;
}
Geocoder geo = new Geocoder(mCtx);
List<Address> addresses = geo.getFromLocation(latitude, longitude, 1);
if (addresses.isEmpty()) {
return null;
} else {
if (addresses.size() > 0) {
m = addresses.get(0).getFeatureName() + ", " + addresses.get(0).getLocality() + ", "
+ addresses.get(0).getCountryName();
}
}
} catch (IOException ie) {
log("No connection.");
return null;
} catch (Exception e) {
log("Can't read adress from this cordinates : lat = " + latitude + " long " + longitude); //
return null;
}
return m;
}
/**
* Removes all location updates
*/
public void stop() {
try {
mLocationManager.removeUpdates(mGPSListener);
mLocationManager.removeUpdates(mNETListener);
} catch (Exception e) {
}
}
}
This is my main class for fetching current location and onLocationChanged never gets called. Im testing on emulator, and sending mock longitude and latitude via Emulator Control. Please Help this is driving me mad :(
Stefan was right. You need to do 2 things.
Grant access to mock location. As of now this needs to be specified in a special manifest file under src/debug/AndroidManifest.xml. Create that xml and add this permission to it:
uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
Make sure your location manager is hooked on to the GPS provider and not the network provider. That information can be found here:
http://developer.android.com/guide/topics/location/strategies.html#MockData
You can change the GPS location values of emulator using Emulator control. By doing this (onLocationChanged method will work) you can test your application in Emulator
Problem is on emulator it wont work, but on real device it found my location in sec
In my case, the problem was for the update frecuency of the accelerometer and magnetic_field sensors. Only changed "SensorManager.SENSOR_DELAY_FASTEST" or SensorManager.SENSOR_DELAY_GAME" to "SensorManager.SENSOR_DELAY_NORMAL" and it´s worked correctly.
Curiously, the frecuency of the GPS sensor can be "SensorManager.SENSOR_DELAY_FASTEST" and don´t have any problem.
i am building a simple android application which require me to auto update the location. the auto update location will not only update when resuming the application but must auto update whenever the application is on. this application looks like the same with GPS system that were put inside the car. it get the exact location and always update the current location. i want to the same thing in here. i am building this application on android 2.2.
here is my code:
package com.example.map;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.widget.TextView;
import android.widget.Toast;
public class MapActivity extends Activity implements LocationListener{
private TextView latituteField, longitudeField, accuracyField, altitudeField, bearingField;
private LocationManager locationManager;
private String provider;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
latituteField = (TextView) findViewById(R.id.TextView02);
longitudeField = (TextView) findViewById(R.id.TextView04);
accuracyField = (TextView) findViewById(R.id.textView1);
altitudeField = (TextView) findViewById(R.id.textView2);
bearingField = (TextView) findViewById(R.id.textView4);
// Get the location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the locatioin provider -> use default
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
// Initialize the location fields
if (location != null) {
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
} else {
latituteField.setText("Location not available");
longitudeField.setText("Location not available");
}
}
/* Request updates at startup */
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
/* Remove the locationlistener updates when Activity is paused */
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
int lat = (int) (location.getLatitude());
int lng = (int) (location.getLongitude());
int acc = (int) (location.getAccuracy());
int alt = (int) (location.getAltitude());
int bearing = (int) (location.getBearing());
latituteField.setText(String.valueOf(lat));
longitudeField.setText(String.valueOf(lng));
accuracyField.setText(String.valueOf(acc));
altitudeField.setText(String.valueOf(alt));
bearingField.setText(String.valueOf(bearing));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
this code it only update the location value when im resuming the application (i quit the application then go back to the application). the location will be updated at the viewtext.
i also tried to do while. like this.
if(location != null){
do{
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
locationManager.requestLocationUpdates(provider, 0, 0, this);
}while(location != null);
}
else{
latituteField.setText("Location not available");
longitudeField.setText("Location not available");
}
im adding this to the manifest.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
however, this code makes the application crash in a real phone. is there anyway to get this done?
*note: i tested all this application in my real phone and trying to achieve the current location. the textview suppose to change whenever it gets the new value of the location without pausing or quitting the application.
You have to put your location code inside an ScheduledExecutor Service:
http://developer.android.com/reference/java/util/concurrent/ScheduledExecutorService.html
That one repeats actualization function in the background for example every 30 seconds or whatever time you specify.
Example:
scheduleTaskExecutor= Executors.newScheduledThreadPool(5);
// This schedule a task to run every 10 seconds:
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
//add your code you would like to be executed every 10 seconds.
} catch (IOException e) {
e.printStackTrace();
}
}
}, 0, 10, TimeUnit.SECONDS);
you also might have to add a permission for coarse location.
I want to get latitude and Longitude from the following Android code.
location = locationManager.getLastKnownLocation(provider);
Here i am getting error location is null.
Here is the code:
package com.p;
import android.app.Activity;
import android.os.Bundle;
import android.os.Bundle;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class GooglemapActivity extends Activity implements LocationListener {
private TextView latituteField;
private TextView longitudeField;
private LocationManager locationManager;
private String provider;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
latituteField = (TextView) findViewById(R.id.TextView02);
longitudeField = (TextView) findViewById(R.id.TextView04);
// Get the location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the locatioin provider -> use
// default
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
// Initialize the location fields
if (location != null) {
System.out.println("Provider " + provider + " has been selected.");
int lat = (int) (location.getLatitude());
int lng = (int) (location.getLongitude());
latituteField.setText(String.valueOf(lat));
longitudeField.setText(String.valueOf(lng));
} else {
latituteField.setText("Provider not available");
longitudeField.setText("Provider not available");
}
}
/* Request updates at startup */
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
/* Remove the locationlistener updates when Activity is paused */
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
public void onLocationChanged(Location location) {
int lat = (int) (location.getLatitude());
int lng = (int) (location.getLongitude());
latituteField.setText(String.valueOf(lat));
longitudeField.setText(String.valueOf(lng));
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
}
I have added the following permisions:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
But I am getting the following error:
Provider not available
If the last known location is null, it's because the phone has no last known location. If there is no location cached, you need to request an updated location, either via network, or GPS. Note that this process can take time, so must be done asynchronously.
You need to read this document:
http://developer.android.com/guide/topics/location/obtaining-user-location.html
I also recommend reading this:
http://android-developers.blogspot.co.uk/2011/06/deep-dive-into-location.html
You haven't define a valid Criteria. Define that as follows
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);//true if required
criteria.setBearingRequired(false);//true if required
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
provider = locationManager.getBestProvider(criteria, true);//search for enabled provider
have you switched on GPS in Settings -> Location ?
why do you use (int) (location.getLatitude()) -- latitude/longitude is a float
Think you need to specify from which provider you want to receive updates.
You have two options:
GPS_PROVIDER
NETWORK_PROVIDER
You're probably missing something like this:
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
I think you may want to add the following permission as well, since I am pretty sure that the FINE relies on the COARSE...
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>