I could write code that get user's location and that works fine in API < 23. But in API 23 and above, my code return nothing in Log.
More Details:
I enable manually device's GPS.
In the first run the app request permission and no log returns.
In the next running the app return my prepared Toast (Check your provider).
this is my wrote code:
public class MainActivity extends AppCompatActivity implements LocationListener {private static final int MY_PERMISSIONS_REQUEST_COARSE_LOCATION = 124;
private static final int MY_PERMISSIONS_REQUEST_FINE_LOCATION = 123;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_FINE_LOCATION);
}
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_COARSE_LOCATION);
}
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(new Criteria(), false);
Location location = locationManager.getLastKnownLocation(provider);
if (location == null) {
Toast.makeText(this, "Check your provider", Toast.LENGTH_SHORT).show();
} else {
Log.i("New Location", "lat: " + location.getLatitude());
Log.i("New Location", "lng: " + location.getLongitude());
}
}
@Override
public void onLocationChanged(Location location) {
Log.i("Location", "lat: " + location.getLatitude());
Log.i("Location", "lng: " + location.getLongitude());
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
In Android API 23+ there is a new way to handle permissions considered as "dangerous", that´s the case of android.permission.ACCESS_FINE_LOCATION
and android.permission.ACCESS_COARSE_LOCATION
among others.
You don´t need to handle android.permission.ACCESS_COARSE_LOCATION
if you are already using the android.permission.ACCESS_FINE_LOCATION
.
Please take a look at this link from the official documentation which shows you how to handle permissions at runtime in Android API 23+.
https://developer.android.com/training/permissions/requesting.html
This one might also help you.
https://developer.android.com/guide/topics/location/strategies.html
How to check for permissions:
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.ACCESS_FINE_LOCATION);
How to request for permissions:
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
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(thisActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
// MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
Note that even if you request for permissions at runtime you will still have to keep the permission entry in the android manifest like this:
<manifest ... >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
<uses-feature android:name="android.hardware.location.gps" />
...
</manifest>
After checking and granting permissions you should review the link with the location strategies above, there you can find the details of what you are missing.
Basically you are not registering the listener to receive the location updates. After adding this line at the end of the onCreate()
method you should start seeing the location updates in your log.
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);