I am trying to fetch my current location through WiFi from Android virtual device but when I debug this program it shows me Null for location in Passive Network provider in getLocation().It gives me value for location manager. In this my gpsProvider, and NetworkProvider both return false value and provider is passive only.
import java.util.List;
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.support.v4.app.FragmentActivity;
import android.util.Log;
public class ShowLocation extends FragmentActivity
{
Context context;
private LocationManager locationManager=null;
private LocationListener locationListener=null;
private Location location=null;
double latitude,longitude;
boolean gpsStatus=false,NetworkProvider=false,Status=false,Passiveprovider=false;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
private Criteria criteria=null;
String Provider=null;
public void onCreate(Bundle state)
{
super.onCreate(state);
setContentView(R.layout.fragment_main);
context=getApplicationContext();
if(Status=checkStatus())
{
getLocation();
}
}
public boolean checkStatus()
{
boolean status1=false;
locationManager=(LocationManager)getSystemService(LOCATION_SERVICE);
List<String> provider =locationManager.getAllProviders();
System.out.println("Location Manager ="+provider);
for(String providername : provider)
{
if(providername.equals(LocationManager.GPS_PROVIDER))
{
gpsStatus=locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
status1=true;
}
if(providername.equals(LocationManager.NETWORK_PROVIDER))
{
NetworkProvider=locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
status1=true;
}
if(providername.equals(LocationManager.PASSIVE_PROVIDER))
{
Passiveprovider=locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
status1=true;
}
}
System.out.println("Network provider ="+NetworkProvider + "Gps Provider ="+gpsStatus + "PassiveProvider ="+Passiveprovider);
return status1;
}
public void getLocation()
{
locationListener=new LocationLis();
if(gpsStatus)
{
System.out.println("Gps Provider = "+gpsStatus);
Log.d("Gps is on","=" +gpsStatus);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,locationListener);
criteria=new Criteria();
Provider=locationManager.getBestProvider(criteria, true);
if(locationManager !=null)
{
location=locationManager.getLastKnownLocation(Provider);
if(location != null)
{
latitude=location.getLatitude();
longitude=location.getLongitude();
System.out.println("Gps Provider");
System.out.println(latitude +" "+longitude);
}
}
}
else if(NetworkProvider)
{
System.out.println("NetworkProvider"+NetworkProvider);
Log.d("Network is on", "="+NetworkProvider);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0,locationListener);
criteria=new Criteria();
Provider=locationManager.getBestProvider(criteria, true);
if(locationManager !=null)
{
location=locationManager.getLastKnownLocation(Provider);
if(location !=null)
{
latitude=location.getLatitude();
longitude=location.getLongitude();
System.out.println("Network Provider");
System.out.println(latitude +" "+longitude);
}
}
}
else if(Passiveprovider)
{
System.out.println("PassiveProvider"+Passiveprovider);
Log.d("Network is on", "="+Passiveprovider);
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,0,0,locationListener);
criteria=new Criteria();
Provider=locationManager.getBestProvider(criteria, true);
// Here Provider is null
if(locationManager !=null)
{
location=locationManager.getLastKnownLocation(Provider);
if(location !=null)
{
latitude=location.getLatitude();
longitude=location.getLongitude();
System.out.println("Network Provider");
System.out.println(latitude +" "+longitude);
}
}
}
else
{
System.out.println("Provider r not available");
}
}
private class LocationLis implements LocationListener
{
#Override
public void onLocationChanged(Location location)
{
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}
Manifest.xml file
android:glEsVersion="0x00020000"
android:required="true" />
<uses-feature
android:name="android.hardware.wifi"
android:required="true" />
<permission
android:name="com.Priyank.priyankcurrentlocation.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="com.Priyank.priyankcurrentlocation.MAPS_RECEIVE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="I have key with me." />
getLastKnownLocation is allowed to return null. It means it hasn't recently figured out a location, or the location it has is so old it doesn't want to return it. You need to account for this possibility. That's one of the two reasons you need to be careful with getLastKnownLocation (the other being that even if it does return a value, it could be really wrong- as in hours old, there is no promise of freshness with it).
Related
I have an android application that will track a users location. It is set so it will use Wifi/Network location services if possible else GPS_PROVIDER services. When there is a wifi connection it works perfectly but when I set to only get location from GPS the app crashes. From testing I have the line location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); isn't actually setting the location but rather it is still null. Anyone know why this is happening?
package temp;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.content.DialogInterface;
import android.provider.Settings;
import android.util.Log;
import java.util.List;
import java.util.Locale;
public class GPSTracker implements LocationListener {
private Context context;
boolean isGPSEnabled = false;
boolean isNetworkEnabled;
Location location;
boolean canGetLocation = false;
Geocoder geocoder;
List<Address> addresses;
double latitude;
double longitude;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0;
private static final long MIN_TIME_BW_UPDATES = 5 * 1000;
protected LocationManager locationManager;
public GPSTracker(Context context){
this.context = context;
getLocation();
}
public Location getLocation(){
try{
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(!isGPSEnabled && !isNetworkEnabled){
showSettingsAlert();
}else{
this.canGetLocation = true;
if(isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
geocoder = new Geocoder(context, Locale.getDefault());
this.addresses = geocoder.getFromLocation(latitude, longitude, 1);
}
}
}else{
Log.e("GPS_Provider: ", "Made it");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if(locationManager == null){
Log.e("GPS_Provider: ", "Manager1");
}else{
Log.e("GPS_Provider: ", "Manager2");
}
if(locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location == null){
Log.e("GPS_Provider: ", "Made it2");
}else{
Log.e("GPS_Provider: ", "Made it3");
}
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.e("Cords: ", "latitude: " + latitude + " longitude: " + longitude);
geocoder = new Geocoder(context, Locale.getDefault());
this.addresses = geocoder.getFromLocation(latitude, longitude, 1);
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
return location;
}
public void stopUsingGps(){
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
public List<Address> getAddress(){
return this.addresses;
}
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
return longitude;
}
public boolean canGetLocation(){
return this.canGetLocation;
}
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setTitle("GPS is settings");
alertDialog.setMessage("GPS is not enabled.");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="temp" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".login"
android:label="#string/title_activity_login" >
</activity>
<activity
android:name=".Register"
android:label="#string/title_activity_register" >
</activity>
</application>
</manifest>
You are getting null as a return because if the GPS never actually obtained a last location it would have nothing to give you
Instead of LocationManager and managing connectivity issues yourself look into the FusedLocationProviderAPI which draws on the most power efficient method of Location polling available and does all that background work for you.
I have code to get location, which I believe must be working but it doesn't at all:
Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Java:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0,
new MyLocationListener()
);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
System.out.println("location: " + location);
location prints null and the listener never get called at all. Anyone can advise what's wrong? If I open Google Maps, it can return my location anyway.
Note: I am testing with my device
Create Class SingleShotLocationProvider in your utility package or wherever you are fine with below code.
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.widget.Toast;
public class SingleShotLocationProvider {
public interface LocationCallback {
void onNewLocationAvailable(Location location);
}
// calls back to calling thread, note this is for low grain: if you want higher precision, swap the
// contents of the else and if. Also be sure to check gps permission/settings are allowed.
// call usually takes <10ms
public static void requestSingleUpdate(final Context context, final LocationCallback callback) {
final LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (Utility.checkAndRequestPermissionsForGPS(context)) {
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context, "First enable LOCATION ACCESS in settings.", Toast.LENGTH_LONG).show();
return;
}
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}, null);
} else {
boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (isNetworkEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}, null);
}
}
}
}
}
Now in you Activity import it like
import com.yourdomain.utils.SingleShotLocationProvider;
Now you can use it like below this is reference to your activity
SingleShotLocationProvider.requestSingleUpdate(this,
new SingleShotLocationProvider.LocationCallback() {
#Override
public void onNewLocationAvailable(Location location) {
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
}
}
});
You will receive location in first attempt just make sure GPS is on and set to high accuracy.And in manifest you have given necessary permission as like below -
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Try this code. I am using the GPS here to get the latitude and longitude.
Criteria criteria = new Criteria();
// Getting the name of the best provider
provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location
location = locationManager.getLastKnownLocation(provider);
if (location != null) {
System.out.println("Get Last LOcation" + location.getLatitude()
+ location.getLongitude());
loc.setLatitude(location.getLatitude());
loc.setLongitude(location.getLongitude());
}
locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
if (location.getAccuracy() < 50) {
locationManager.removeUpdates(locationListener);
}
}
};
locationManager.requestLocationUpdates(provider,
INTERVAL_TIME_SECONDS, MIN_DISTANCE_METERS,
locationListener);
For some unclear reason I am not getting any locations, and onLocationChanged() is not invoked.
package com.example.gpsexample;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
public class GPS_Location extends Activity implements LocationListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("~~~","~~~ GPS_Location onCreate");
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
Location l1 = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location l2 = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Log.d("~~~","~~~ GPS_Location getLastKnownLocation ==> "+l1+" "+l2);
r.run();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onLocationChanged(Location location) {
Log.d("~~~","~~~ onLocationChanged "+location);
int latitude = (int) (location.getLatitude());
int longitude = (int) (location.getLongitude());
Log.i("~~~", "### Latitude: " + latitude + ", Longitude: " + longitude+"\n\n\n###");
}
#Override
public void onProviderDisabled(String provider) {
Log.d("~~~","~~~ onProviderDisabled"+provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.d("~~~","~~~ onProviderEnabled "+provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("~~~","~~~ "+provider+" "+status+" "+extras);
}
final Handler handler = new Handler();
Runnable r = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Log.d("~~~","~~~ GPS_Location run");
Location l = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Log.d("~~~","GPS enabled: "+locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER));
Log.d("~~~","~~~ GPS_Location getLastKnownLocation ==> "+l);
l = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Log.d("~~~","Network enabled: "+locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER));
Log.d("~~~","~~~ Network_Location getLastKnownLocation ==> "+l);
handler.postDelayed(this, 5000);
}
};
}
the permissions are:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
/>
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
/>
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
/>
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"
/>
<uses-permission
android:name="android.permission.INTERNET"
/>
and the output is:
D/~~~ (29852): ~~~ GPS_Location run
D/~~~ (29852): GPS enabled: true
D/~~~ (29852): ~~~ GPS_Location getLastKnownLocation ==> null
D/~~~ (29852): Network enabled: true
D/~~~ (29852): ~~~ Network_Location getLastKnownLocation ==> null
When I change the location settings, I do see onProviderEnabled() calls.
How do I get a location instead of null?
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
Update Location
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Please Update In Your Code
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 60 * 1, 10, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60 * 1, 10, this)
I have a code to get location from GPS, but if there is no GPS enabled then i want to use the Network. The GPS Section is working so far, but the NETWORK section returns null location, why is that?. here is my code.
private static final long MINIMUNDIST = 1;
private static final long MINTME = 1000;
protected LocationManager locationMan;
protected Button mybutton;
mybutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
showCurrentLocation();
}
});
protected void showCurrentLocation(){
boolean gpsOn = locationMan.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean netOn = locationMan.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Location loc;
if (gpsOn){
loc = locationMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
else if (netOn){
loc = locationMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
else{
Toast.makeText(MainActivity.this, "BOth GPS and NETWORK are OFF", Toast.LENGTH_SHORT).show();
loc = null;
}
if (loc != null){
String latText = String.format("%1$s" , loc.getLatitude());
String logText = String.format("%1$s" , loc.getLongitude());
TextView latTView = (TextView) findViewById(R.id.textView1);
TextView longtext = (TextView) findViewById(R.id.TextView01);
latTView.setText("Latitude :" + latText);
longtext.setText("Longtude :" + logText);
}
else{
Toast.makeText(MainActivity.this, "Null location?!!" , Toast.LENGTH_SHORT).show();
}
}
private class MyLocationListener implements LocationListener {
public void onLocationChanged(Location location) {
}
public void onStatusChanged(String s, int i, Bundle b) {
}
public void onProviderDisabled(String s) {
}
public void onProviderEnabled(String s) {
}
}
my manifest file contains all the permission needed for the task
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
And by the way, i am testing the app on real phone via USB debugging.
I recently worked on GPS as well and I followed, this tutorial, and it works okay (you may need to fix some portion to make functional for other features..)
public Location getLocation(){
try{
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
//getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
//getting network status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(!isGPSEnabled){
}else{
this.canGetLocation = true;
if(isNetworkEnabled){
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if(locationManager != null){
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
speed = location.getSpeed();
}
}
}
if(isGPSEnabled){
if(location == null){
locationManager.requestLocationUpdates((LocationManager.GPS_PROVIDER), MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if(locationManager != null){
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
return location;
}
And you must add the required permissions to the AndroidManifest.xml file as below
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Just for Testing you can add one more permission to use mock location.
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
The location listener method returns null until it founds a lock on a location.The Network provider location takes few seconds or even minutes to have a lock on a location so it is required to wait until there is a lock on a location.
I tried to get latitude and longitude for current location.
However, when I use the code below, the location listener is not triggered at all.
I've added the LOCATION permission in manifest file.
anyone can help?
Here is the java code:
package com.example.setlocaction;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends Activity{
double latitude, longitude, radius;
LocationManager mlocManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Acquire a reference to the system Location Manager
mlocManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener()
{
public void onLocationChanged(Location loc)
{
// Called when a new location is found by the network location provider.
Log.i("loc","location changed");
if (loc!=null)
{
loc.getLatitude();
loc.getLongitude();
String Text = "My current location is: " +
"Latitud =" + loc.getLatitude() +
"Longitud = " + loc.getLongitude();
Toast.makeText( getApplicationContext(),Text,Toast.LENGTH_SHORT).show();
}
}
public void onStatusChanged(String provider, int status, Bundle extras)
{}
public void onProviderEnabled(String provider)
{}
public void onProviderDisabled(String provider)
{}
};
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
// 高精度
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = mlocManager.getBestProvider(criteria, true);
mlocManager.requestLocationUpdates(provider, 2000, 0, locationListener);
Location loc=mlocManager.getLastKnownLocation(provider);
if (loc==null)
{
Log.i("loc","loc=null");
}
}
}
mafinest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.setlocaction"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.setlocaction.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
First of all, your current solution utilizes "getLastKnownLocation" which means, that if you actually retrieve the longitude and latitude, you cannot be certain that it will return the current position of the user. It simply returns the location which was last found which can be miles away.
That is nothing wrong in doing so, but it leaves for uncertainty.
Instead, I have personally implemented a location manager for retrieving the current position of the user by utilizing the code provided in the following post which works great:
https://stackoverflow.com/a/17290348/2399772
By using this specific code, you will also be given the advantage that it tries to utilize the WiFi connection first for determining the position which is slightly better. It that doesn't work, it will utilize the GPS instead. Additionally, if GPS services aren't enabled, a dialogue will be shown telling the user to enable those.
Hope this helps.
Additional notes
As I have stated in a previous post, the Geolocation API will does unfortunately not work on all devices. You can hereby consider using the Reverse Geocoding API instead, which is additionally much more reliable:
https://developers.google.com/maps/documentation/geocoding/
It simply requires that you send a HTTP request which should contain latitude and longitude, whereafter it will provide a response in JSON which is easily parsed.
Sometimes it takes a while for the device to deliver the first locations if you haven't used the GPS before. Also, make sure you're in a location where you can gps updates, or try on the emulator using geo fix via telnet.
try this
public class MyLocationActivity extends Activity implements LocationListener {
private LocationManager mgr;
private String best;
public static double myLocationLatitude;
public static double myLocationLongitude;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
dumpProviders();
Criteria criteria = new Criteria();
best = mgr.getBestProvider(criteria, true);
Log.d("best provider", best);
Location location = mgr.getLastKnownLocation(best);
dumpLocation(location);
//may be some intent here
}
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
dumpLocation(location);
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
protected void onPause() {
super.onPause();
mgr.removeUpdates(this);
}
#Override
protected void onResume() {
super.onResume();
mgr.requestLocationUpdates(best, 15000, 1, this);
}
private void dumpLocation(Location l) {
if (l == null) {
myLocationLatitude = 0.0;
myLocationLongitude = 0.0;
} else {
myLocationLatitude = l.getLatitude();
myLocationLongitude = l.getLongitude();
}
}
private void dumpProviders() {
List<String> providers = mgr.getAllProviders();
for (String p : providers) {
dumpProviders(p);
}
}
private void dumpProviders(String s) {
LocationProvider info = mgr.getProvider(s);
StringBuilder builder = new StringBuilder();
builder.append("name: ").append(info.getName());
}
}
Add following code to your java file
private void GetLocation()
{
LocationDetail pref_LocationDetail = new LocationDetail(_context);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(objCommon.isOnline(_context))
{
if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER ,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationListener()
);
return ;
}
else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER ,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationListener()
);
return ;
}
}
}
private class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location location)
{
LocationDetail pref_LocationDetail = new LocationDetail(_context);
double Lattitude = location.getLatitude();
double Longitude = location.getLongitude();
Toast.makeText(_context , location.getProvider().toString() , Toast.LENGTH_LONG).show();
locationManager.removeUpdates(this);
locationManager = null;
}
public void onStatusChanged(String s, int i, Bundle b) {
Toast.makeText(_context , "Provider status changed",
Toast.LENGTH_LONG).show();
}
public void onProviderDisabled(String s) {
Toast.makeText(_context ,
"Provider disabled by the user. GPS turned off",
Toast.LENGTH_LONG).show();
}
public void onProviderEnabled(String s) {
Toast.makeText(_context ,
"Provider enabled by the user. GPS turned on",
Toast.LENGTH_LONG).show();
}
}
just add following code in your manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />