2

I'm trying to make that when I load my map activity, a "my location" button will appear. This is my code, and the button which makes my activity to zoom in to my current location isn't appearing. What do I need to change in my code to make it work?

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private static final String FIREBASE_URL="https://********.firebaseio.com/";
private Firebase firebaseRef;
private LocationManager locationManager;
private GoogleMap mMap;
SupportMapFragment mapFrag;
boolean bPermissionGranted;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps2);
    Firebase.setAndroidContext(this);
    firebaseRef = new Firebase(FIREBASE_URL);
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        bPermissionGranted = checkLocationPermission();
    }
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);





    }
private void setUpMapIfNeeded() {
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();

        if (mMap != null) {


            CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(32.065483, 34.824550));
            CameraUpdate zoom = CameraUpdateFactory.zoomTo(10);
            mMap.moveCamera(center);
            mMap.animateCamera(zoom);

        }
    }
}

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
    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)) {

            // 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.
            //  TODO: Prompt with explanation!

            //Prompt the user once explanation has been shown
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);

        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}



 @Override
 public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay!
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
                        ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    mMap.setMyLocationEnabled(true);
                }
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
            }
            return;
        }

    }
}


@Override
public void onMapReady(final GoogleMap googleMap) {

    mMap=googleMap;

    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (bPermissionGranted) {
            //User has previously accepted this permission
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
                    ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                mMap.setMyLocationEnabled(true);
            }
        }
    }
    else {
        //Not in api-23, no need to prompt
        mMap.setMyLocationEnabled(true);
    }

    firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            for (DataSnapshot child : dataSnapshot.child("users").getChildren()) {


                String rightLocation = child.child("location_right").getValue().toString();
                String leftLocation = child.child("location_left").getValue().toString();

                double location_left = Double.parseDouble(leftLocation);
                double location_right = Double.parseDouble(rightLocation);
                String party_title = child.child("party/party_title").getValue().toString();
                LatLng cod = new LatLng(location_left, location_right);
                googleMap.addMarker(new MarkerOptions().position(cod).title(party_title));


            }
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });
}
}
ArK
  • 20,698
  • 67
  • 109
  • 136
Gilad Neiger
  • 643
  • 1
  • 6
  • 15

3 Answers3

3

This is a simplified version of my other answer that also requests location updates .

The key is just to make sure that the user has granted you permission before you make the call to setMyLocationEnabled().

It's also possible that the user has not accepted the permission prompt by the time onMapReady() is called (most likely on first launch of the app), therefore there's another call to setMyLocationEnabled() in the onRequestPermissionsResult() callback in the case that the user accepted the permission.

First, ensure that you have the permissions in your AndroidManifest.xml (outside of the application tag):

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Here is a full Activity class that will work for you:

public class MapLocationActivity extends AppCompatActivity
        implements OnMapReadyCallback {

    GoogleMap mGoogleMap;
    SupportMapFragment mapFrag;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkLocationPermission();
        }

        mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFrag.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //User has previously accepted this permission
            if (ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                mGoogleMap.setMyLocationEnabled(true);
            }
        } else {
            //Not in api-23, no need to prompt
            mGoogleMap.setMyLocationEnabled(true);
        }
    }

    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

    public boolean checkLocationPermission() {
        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)) {

                // 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.
                //  TODO: Prompt with explanation!

                //Prompt the user once explanation has been shown
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);

            } else {
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);
            }
            return false;
        } else {
            return true;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay!
                    if (ActivityCompat.checkSelfPermission(this,
                            Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        mGoogleMap.setMyLocationEnabled(true);
                    }
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
                }
                return;
            }

        }
    }
}

If you revoke the permission:

enter image description here

It will prompt again:

enter image description here

Community
  • 1
  • 1
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
  • I've tried your answer, but there is an error message on every time this line is written: `mMap.setMyLocationEnabled(true);`. The error says: _call requires permission which may be rejected by user: code should explictly check if permission is available (with 'checkPermission') or explictly handle a potential 'SecurityExpection'_ – Gilad Neiger Apr 09 '16 at 08:10
  • And its even not asking me a permission to use my locations in my phone. – Gilad Neiger Apr 09 '16 at 09:14
  • @olash12345 I just updated the answer again to simplify it even more. With the added checks necessary, there was no need for the boolean. I just tested this on both a Nexus 5 with 6.0.1, and a Nexus 6 with 6.0.1, and it prompts for the Location permission, and then enables the MyLocaction button, which works as expected. – Daniel Nugent Apr 09 '16 at 09:24
  • It is not asking me a permission. And also it is not showing the button. Do I have to call the function `onMapReady()` somewhere? – Gilad Neiger Apr 09 '16 at 09:47
  • @olash. No, onMapReady() gets called after you call getMapAsync(). Not sure why it's not working for you, it works just fine for me. Check your logs for possible errors. – Daniel Nugent Apr 09 '16 at 17:00
  • I think I know what is the problem. The permission request dialog is not showing up for me and because of that it is not showing the location button. Why is the permission request dialog isn't showing up? – Gilad Neiger Apr 09 '16 at 17:17
  • @olash12345 Do you have the permissions in your AndroidManifest.xml? Also, check your logs again, there is probably an error being logged that will tell you what the problem is. – Daniel Nugent Apr 09 '16 at 17:57
  • This is written in my logcat, maybe this is the reason that my permission requests aren't showing up? `I/Choreographer: Skipped 46 frames! The application may be doing too much work on its main thread.` @Daniel Nugent – Gilad Neiger Apr 10 '16 at 13:04
  • I've solved my request permissions problem! See my answer here: http://stackoverflow.com/questions/36529635/app-requests-arent-showing-up/36557669#36557669 Your answer is working for me. thanks alot! – Gilad Neiger Apr 11 '16 at 19:35
0

You are using the same condition in if and else both blocks.

 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) 

So, if your above condition is not true then how will be the same condition gets true in your else block. That's the reason mMap.setMyLocationEnabled(true); never gets executed because your condition is false.

I guess what you want to do in else block is to request for permissions if it is not there. So it will change like this -

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    mMap.setMyLocationEnabled(true);
   } else{

       ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, <request_code>);
    }

And implement onRequestPermissionsResult callback

 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case <request_code>:
                if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                     mMap.setMyLocationEnabled(true);
                }
                break; 
        }
    }
Shadab Ansari
  • 7,022
  • 2
  • 27
  • 45
  • Hey, I've tried your answer, and there are two errors appearing: 1) What are you trying to do in this line `case :`? It causes an error. 2) This line shows an error: `mMap.setMyLocationEnabled(true);` which says: call requires permission which may be rejected by user: code should explictly check if permission is available (with 'checkPermission') or explictly handle a potential 'SecurityExpection' – Gilad Neiger Apr 09 '16 at 08:15
0

Please write N instead of M after Build.VERSION_CODES.

In this line in your code:

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)

it worked for me

T.Rashid
  • 43
  • 8