Search code examples
androidandroid-6.0-marshmallowandroid-geofence

Android permission for android M doesnt work


Here is my MapsActivity.java file, i have used the RequestPermission callback and everything yet the dialogbox asking me to grant location permission doesnt show up and the app crashes! package saksham.geofencing;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGeofences = new ArrayList<Geofence>();
        mGeofenceCoordinates = new ArrayList<LatLng>();
//        double string0=prefenceSettings.getString("LatLng0", "34");

        setContentView(R.layout.activity_maps);
        showHelpForFirstLaunch();
        SupportMapFragment supportMapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap);
        cd = new ConnectionDetector(getApplicationContext());
        isInternetPresent = cd.isConnectingToInternet();

        // check for Internet status
        if (isInternetPresent) {
            // Internet Connection is Present
            // make HTTP requests
                    } else {
            // Internet connection is not present
            // Ask user to connect to Internet
            showAlertDialog(MapsActivity.this, "No Internet Connection",
                    "You don't have internet connection.");
        }
        /**
         * SupportMapFragment belongs to the v4 support library, contrary to the default MagFragment that is a native component in Android.
         SupportMapFragment will support more Android versions, but it is also an additional library you have to add in your project,
         so I think it really depends on the Android versions you are targeting:
         •  On recent versions, the default components should be enough
         •  On older versions you will need to install the v4 support library and maybe others
         *
         */
        db = openOrCreateDatabase("geofence", Context.MODE_PRIVATE, null);
        db.execSQL("CREATE TABLE IF NOT EXISTS Coordinates(id INTEGER,latitude DOUBLE,longitude DOUBLE,true VARCHAR);");
        db.execSQL("INSERT INTO Coordinates VALUES(0,0,0,'0')");
        db.execSQL("INSERT INTO Coordinates VALUES(1,0,0,'0')");
        db.execSQL("INSERT INTO Coordinates VALUES(2,0,0,'0')");
        googleMap = supportMapFragment.getMap();
        Log.i("My activity", "maps=" + googleMap);
        googleMap.setMyLocationEnabled(true);
        /**
         * setMyLocationEnabled(true/false) shows the true location when the GPS is switched on from the device. It is an inbuilt feature of the googlemaps .
         */

        LocationManager locationManager = (LocationManager) getSystemService(Service.LOCATION_SERVICE);
        // getting GPS status
        boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if(!isGPSEnabled)
        {
            Utils.displayPromptForEnablingGPS(this);
        }
        Log.i("My activity", "gps is" + isGPSEnabled);

        // getting network status
        boolean isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        Log.i("My activity", "network is" + isNetworkEnabled);

        Criteria crta = new Criteria();
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
            crta.setAccuracy(Criteria.ACCURACY_FINE);
        } else {
            crta.setAccuracy(Criteria.ACCURACY_MEDIUM);
        }
        /**
         * we have used .setAccuracy as fine for higher SDks than gingerbread .Gingerbread is used as a reference because in apks lower
         * than gingerbread there is very poor geo-fencing, with gingerbread google made it a lot easier for location services to be used for devleopers.
         * it had improved set of tools for Location Services, which included geofencing and substantially improved location discovery.
         */
        crta.setPowerRequirement(Criteria.POWER_LOW);
        String provider = locationManager.getBestProvider(crta, true);

        /**
         * It request Location updates after every 5 sec or if the user traveled 10m
         */
        Log.i("My activity", "manager is " + locationManager);
        Log.i("My activity", "provider is " + provider);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.ACCESS_COARSE_LOCATION}, 100);

                return;
            }
        }
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) this)
                    .addOnConnectionFailedListener((GoogleApiClient.OnConnectionFailedListener) this)
                    .addApi(LocationServices.API)
                    .build();
            mGoogleApiClient.connect();
            Log.i("Api is", "" + mGoogleApiClient);
        }
        mLocationRequest = new LocationRequest();
        // We want a location update every 10 seconds.
        mLocationRequest.setInterval(10000);
        // We want the location to be as accurate as possible.
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);


        insertgeofence();


    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 100: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Thanks for the permission", Toast.LENGTH_LONG).show();
                    // permission was granted, yay! do the
                    // calendar task you need to do.
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "You did not allow to access your current location", Toast.LENGTH_LONG).show();
                }
            }
            // other 'switch' lines to check for other
            // permissions this app might request
        }
    }


    @Override
    public void onLocationChanged(Location location) {
        latitude=location.getLatitude();
        longitude=location.getLongitude();
        CameraPosition INIT =
                new CameraPosition.Builder()
                        .target(new LatLng(latitude, longitude))
                        .zoom(17.5F)
                        .bearing(300F) // orientation
                        .tilt(50F) // viewing angle
                        .build();
        // use GooggleMap mMap to move camera into position
        googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(INIT));
    }

    @Override
    public void onConnected(Bundle bundle) {
        Location mlastlocation;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);

                return;
            }
        }
        mlastlocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        startLocationUpdates();
        if (mlastlocation != null) {
            Log.i("the last location:", "" + mlastlocation);
//            Toast.makeText(this, "Get last location first asshole!", Toast.LENGTH_LONG).show();
        }


    }


    protected void startLocationUpdates() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);

                return;
            }
            LocationRequest mLocationRequest = new LocationRequest();

            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        }
    }

    }

Solution

  • You are calling googleMap.setMyLocationEnabled(true) before checking for permissions. Also, you should instantiate any location code AFTER you check the permissions. Also, in your onRequestPermissionsResult, you may want to add in the location code you want initiated.