I'm trying to implement location permissions in Android Marshmallow. I created a small test application, and everything is working perfectly. But when I copy that same code into my real application, the dialog "Allow [app name] to access this device's location?" never appears.
I can step through the debugger and see that ActivityCompat.requestPermissions() is called when it should be.
The only difference I can think of is that the real app has a lot more going on. The map activity is created from within a ScrollableTabActivity, like this:
this.addTab(getString(R.string.map), R.drawable.iconmap,
RadioStateDrawable.SHADE_GRAY,
RadioStateDrawable.SHADE_BLUE, new Intent(this, MapsActivity.class));
Do I need to think about threads, or anything like that? Or creating the activity in a different way?
Here's the full source code to the sample activity (where everything works):
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {
private GoogleMap map;
private Button gpsButton;
private static String[] LOCATION_PERMISSIONS = {Manifest.permission.ACCESS_FINE_LOCATION};
private static int ACCESS_FINE_LOCATION_PERMISSION_REQUEST_CODE = 1;
private LocationManager locationManager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
gpsButton = (Button) findViewById(R.id.GPS);
gpsButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
requestLocationPermissions();
}
});
}
private void requestLocationPermissions()
{
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
{
new AlertDialog.Builder(MapsActivity.this)
.setMessage("Without access to your location, the app's location function cannot be used. Will you allow this access?")
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
ActivityCompat.requestPermissions(MapsActivity.this,
LOCATION_PERMISSIONS, ACCESS_FINE_LOCATION_PERMISSION_REQUEST_CODE);
}
}).setNegativeButton(R.string.no, null).show();
}
else
{
ActivityCompat.requestPermissions(this, LOCATION_PERMISSIONS, ACCESS_FINE_LOCATION_PERMISSION_REQUEST_CODE);
}
}
else
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults)
{
if (requestCode == ACCESS_FINE_LOCATION_PERMISSION_REQUEST_CODE)
{
if (verifyPermissions(grantResults))
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
else
{
new AlertDialog.Builder(MapsActivity.this)
.setMessage("Without access to your location, the app's location function cannot be used.")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
}
}).show();
}
}
}
private void updateUserLocation(Location location)
{
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
locationManager.removeUpdates(this);
}
public static boolean verifyPermissions(int[] grantResults)
{
boolean verified = false;
for (int result : grantResults)
{
if (result == PackageManager.PERMISSION_GRANTED)
{
verified = true;
}
}
return verified;
}
@Override
public void onMapReady(GoogleMap googleMap)
{
map = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
map.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
map.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
@Override
public void onLocationChanged(Location location)
{
updateUserLocation(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
@Override
public void onProviderEnabled(String provider)
{
}
@Override
public void onProviderDisabled(String provider)
{
}
}