I am creating an Android application to get my current GPS location. First it was working, but now it always returns null. It just shows the GPS icon in my phone's notification bar but the icon is not getting activated or highlighted. I tried many tricks but nothing have worked so far. Here is my code:
final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@SuppressLint("RestrictedApi")
@Override
public void onClick(View view) {
fab.setVisibility(View.VISIBLE);
GpsTracker gt = new GpsTracker(getApplicationContext());
Location l = gt.getLocation();
if(l != null) {
double lat = l.getLatitude();
double lon = l.getLongitude();
Toast.makeText(getApplicationContext(),"GPS Lat = "+lat+"\n lon = "+lon,Toast.LENGTH_SHORT).show();
Snackbar.make(view, "GPS Lat = "+lat+"\n lon = "+lon, Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
} else {
Snackbar.make(view, "GPS unable to Connect", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Toast.makeText(getApplicationContext(),"GPS unable to Connect",Toast.LENGTH_SHORT).show();
}
}
});
GpsTracker.java
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import static android.content.Context.LOCATION_SERVICE;
public class GpsTracker implements LocationListener {
public Context context;
public GpsTracker(Context context) {
super();
this.context = context;
}
public Location getLocation(){
if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
Log.e("fist","error");
return null;
}
try {
LocationManager lm = (LocationManager) context.getSystemService(LOCATION_SERVICE);
boolean isGPSEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 6000,10,this);
Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
return loc;
} else {
Log.e("sec","Please enable your GPS");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@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) {
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Hassan,
Have you considered using the Google Services in retrieving one's location. I prefer using that. Below find an example, however you will need to
Set up the Google API key on the Google API console : https://console.developers.google.com/?pli=1
Choose the Maps SDK for Android and Enable it, then generate the API Key therein.
Copy and paste the API key on your strings.xml file in your Project
Add the following dependency in your app.gradle file
implementation 'com.google.android.gms:play-services-maps:16.1.0'
Add the following in your AndroidManifest.xml , after the application tag
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_maps_key" />
Implement the following Classes
public class MainActivity extends AppCompatActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
/*Declare the following Variables */
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private boolean mRequestingLocationUpdates = false;
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FATEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 10; // 10 meters
public GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
Location mLastLocation;
public static double lat = 0, lng = 0;
LocationManager locationManager;
Location location = null;
Create the following functions outside the OnCreate Function
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
createLocationRequest();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
@SuppressLint("MissingPermission")
protected void startLocationUpdates() {
try {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (LocationListener) this);
} catch (Exception e) {
Log.d("LOCATION_MSG", e.getMessage());
}
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (LocationListener) this);
}
Call the buildGoogleApiClient() in your onCreate
Override the methods
@Override
public void onConnected(@Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@SuppressLint("MissingPermission")
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
}
@Override
public void onMapReady(GoogleMap googleMap) {
}
In your OnClick Listener :
fab.setOnClickListener
Add this
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
startLocationUpdates();
if (mLastLocation != null)
{
try {
lat = mLastLocation.getLatitude();
lng = mLastLocation.getLongitude();
} catch (Exception e) {
lat = 0;
lng = 0;
}
/* Check your log cat for the following */
Log.d("LOC_Latitude" , Double.toString(lat));
Log.d("LOC_Longitude" , Double.toString(lng));
}else{
//Something is a miss, maybe the location service on your phone is not on, it could even be the internet connection.
}
Things to Note Ensure you have all the prerequisite permissions on your manifest , some devices would require permissions to be requested on run time. You can use the following to do that
/*Declare this method outside our onCreate Function */
public static boolean hasPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
/*Add this in your onCreate Function */
String[] PERMISSIONS = {Manifest.permission.INTERNET, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
if (!hasPermissions(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, 1);
}
Also make sure you have the following permissions on your AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<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_WIFI_STATE" />
Try that and revert in any case you are still stuck.