2

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)
{
}

}

steverb
  • 1,415
  • 1
  • 10
  • 12
  • In your real application, what is your `targetSdkVersion`? – CommonsWare May 18 '16 at 20:26
  • Both the real application and the test application are the same: – steverb May 19 '16 at 02:32
  • minSdkVersion 15 targetSdkVersion 23 – steverb May 19 '16 at 02:33
  • I can think of one other difference. In the real application I have: `code` public class MapsActivity extends Activity implements LocationListener and in the test application I have: `code` public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener But I did try extending FragmentActivity in the real application and it made no difference. – steverb May 19 '16 at 14:47
  • I got it working now, but I don't understand why this worked. The activity I was putting all the location related code was a mapactivity. As soon as I moved the code to it's parent (a customslidingtabhost) then everything started working as expected. There was a similar discussion here: [link]http://stackoverflow.com/questions/37140519/activitycompat-requestpermissions-does-not-show-prompt but their results were almost the opposite. – steverb Jun 08 '16 at 19:32

0 Answers0