8

I'm attempting to request ACCESS_FINE_LOCATION permissions in order to get the user's current location.

My logging indicates that my app does not currently have this permission when querying ContextCompat.checkSelfPermission(), but when calling ActivityCompat.requestPermissions() nothing is displayed.

My Google map code (implementing OnMapReadyCallback and ActivityCompat.OnRequestPermissionsResultCallback()) is in a FragmentActivity.

I have managed to get the requestPermissions() function working successfully in other Activities in the app, it's just the one with the Google map. It doesn't work when placed in the onCreate() method of the Activity, or in onMapReady() (where it needs to go).

if(ContextCompat.checkSelfPermission(LocationActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        Log.d(TAG, "not granted");
        final String[] permissions = new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION};
    if(ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
            Log.d(TAG, "rationale");
            // Explain to the user why permission is required, then request again
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("We need permissions")
                    .setCancelable(false)
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            ActivityCompat.requestPermissions(LocationActivity.this, permissions, 1);
                    }
                });
        AlertDialog alert = builder.create();
        alert.show();

    } else {
        Log.d(TAG, "request" + android.Manifest.permission.ACCESS_FINE_LOCATION);
        // If permission has not been denied before, request the permission
        ActivityCompat.requestPermissions(LocationActivity.this, permissions, 1);
    }
} else {
    Log.d(TAG, "granted");
}

Any ideas? Is it something to do with my Activity's class (FragmentActivity), or possible the Google map calling the permissions request asynchronously?

Aleksandar G
  • 1,163
  • 2
  • 20
  • 25
Robin
  • 321
  • 1
  • 3
  • 10
  • I am surprised that this compiles. `checkSelfPermission()` uses `LocationActivity.this`. The second `requestPermissions()` uses `PermissionsRequestActivity.this`. – CommonsWare May 10 '16 at 13:53
  • Sorry yes, I had to change my code slightly for posting, the second one should be LocationActivity.this – Robin May 10 '16 at 13:54
  • I had been trying making all requestPermissions in a separate Activity, but this makes the callback difficult, and is hacky. – Robin May 10 '16 at 13:55
  • FWIW, [this sample app](https://github.com/commonsguy/cw-omnibus/tree/master/MapsV2/MyLocationMNC) uses runtime permissions without issue. – CommonsWare May 10 '16 at 13:55
  • Shouldn't you have specified finelocation in the manifest? Or has android changed completely in the last year? – danny117 May 10 '16 at 13:55
  • @CommonsWare I can confirm your sample also works when the AbstractMapActivity extends FragmentActivity too, so I guess it's not related to the map, or that... – Robin May 10 '16 at 14:11

3 Answers3

14

After stripping out my class completely, and it still not working, I realised that this Activity is being instantiated using a TabHost.

When I stop using the TabHost, the prompt is displayed successfully. I guess TabHosts are not supported by the new permissions prompts - is this a bug?

Same problem as App requests aren't showing up

I ended up creating a PermissionsRequestActivity which handles the permission request and response on behalf of my TabHost, then exits (pass the requested permission information in through the Intent extras Bundle).
It passes back the response to the request as a Broadcast, which is picked up by my TabHost.

Bit of a hack but works OK!

Community
  • 1
  • 1
Robin
  • 321
  • 1
  • 3
  • 10
  • Ditto - using TabHost and it ain't showing for me either. Anyone know how to handle? – AlexVPerl Aug 30 '16 at 04:03
  • I ended up creating a PermissionsRequestActivity which handles the permission request and response on behalf of my TabHost, then exits (pass the requested permission information in through the Intent extras Bundle). It passes back the response to the request as a Broadcast, which is picked up by my TabHost. Bit of a hack but works OK! – Robin Aug 31 '16 at 13:24
  • To clarify, the TabActivity itself handles permissions requests fine, but any activities hosted inside it as tabs do not. So I was able to solve this by posting messages up to the main activity and then back to the fragment. – Greg Ennis Oct 21 '16 at 03:11
1

Check that you have already added the requested permission in Android's manifest file like before Android M, only then you will get expected behaviour.

Add the permission to your manifest so you can request it via ActivityCompat.requestPermissions:

<uses-permission android:name="android.permission. ACCESS_FINE_LOCATION" />
Alejandro Casanova
  • 3,633
  • 4
  • 31
  • 46
  • Thanks, I had this; elsewhere in the app the permission request was displaying successfully. I found the cause, see my answer above. – Robin May 23 '16 at 10:31
0

I've faced the same problem on a project which use TabHost. Basis on @Robin solution, I use the EventBus library for send a message from child activity to the TabActity.

EventBus : https://github.com/greenrobot/EventBus

Create an event object :

public class MessageEvent {
    private String message;
    public MessageEvent(String message){
        this.message = message;
    }

    public String getMessage(){
        return this.message;
    }
}

In your main Activity :

private EventBus eventBus = EventBus.getDefault();
@Override
protected void onCreate(Bundle savedInstanceState) {
    eventBus.register(this);
}
@Override
protected void onDestroy() {
    eventBus.unregister(this);
    super.onDestroy();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
    if (event.getMessage().equals("contacts")){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainPage.this,new String[]{android.Manifest.permission.WRITE_CONTACTS}, 100 );
        }
    }
};

Set a different message for the permission your want to request. In your child activity you can than post the adequate message :

EventBus.getDefault().post(new MessageEvent("contacts"));

Be aware of onRequestPermissionsResult callback and the request code ;)! It will only work in the main activity.

Luidgi Gromat
  • 471
  • 4
  • 3