Search code examples
androidruntime-permissions

Permission problems in Location


package com.example.khatrimann.map_activity;

import android.*;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private static final int LOCATION_REQUEST_CODE = 101;
private static final int LOCATION_REQUEST_CODE_2 = 102;
//private   String  TAG = “MapDemo” ;
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;

protected void requestPermission(String permissionType, int
        requestCode) {
    int permission = ContextCompat.checkSelfPermission(this,
            permissionType);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{permissionType}, requestCode
        );
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case LOCATION_REQUEST_CODE: {
            if (grantResults.length == 0
                    || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Unable to show loaction permissions", Toast.LENGTH_LONG).show();
            }
            return;
        }

    }
}

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

    requestPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,
            LOCATION_REQUEST_CODE);

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

//@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    /*// Add a marker in Sydney, Australia, and move the camera.
    LatLng sydney = new LatLng(-34, 151);
    mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));*/


    if (mMap != null) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            //mMap.setMyLocationEnabled(true);

            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

        }
        else {
            requestPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, LOCATION_REQUEST_CODE);
        }

    }
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Toast.makeText(this, "Online", Toast.LENGTH_SHORT).show();

}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }
}

I have added proper permissions in the manifest file, checked the run time permissions, everything is working except mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient).

When the activity is launched then it force stops, no error is sown in studio.

When the activity is launched for the first time (By studio) it gives toast "Unable to show location permissions" as written in code When the activity is launched for second time (manually) it force stops and following error comes:

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                 Process: com.example.khatrimann.map_activity, PID: 17785
                                                                                 java.lang.IllegalArgumentException: GoogleApiClient parameter is required.
                                                                                     at com.google.android.gms.common.internal.zzac.zzb(Unknown Source)
                                                                                     at com.google.android.gms.location.LocationServices.zzj(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzarl.getLastLocation(Unknown Source)
                                                                                     at com.example.khatrimann.map_activity.MapsActivity.onMapReady(MapsActivity.java:95)
                                                                                     at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
                                                                                     at com.google.android.gms.maps.internal.zzt$zza.onTransact(Unknown Source)
                                                                                     at android.os.Binder.transact(Binder.java:499)
                                                                                     at zu.a(:com.google.android.gms.DynamiteModulesB:82)
                                                                                     at maps.ad.t$5.run(Unknown Source)
                                                                                     at android.os.Handler.handleCallback(Handler.java:751)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                     at android.os.Looper.loop(Looper.java:154)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:6126)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Solution

  • You must ask for ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION, if using GoogleMap, also try to optimize your code.

    Your full edited code:

    package com.example.khatrimann.map_activity;
    
    import android.*;
    import android.Manifest;
    import android.content.pm.PackageManager;
    import android.location.Location;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.annotation.RequiresApi;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.content.ContextCompat;
    import android.widget.Toast;
    
    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.location.LocationServices;
    import com.google.android.gms.maps.CameraUpdateFactory;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.OnMapReadyCallback;
    import com.google.android.gms.maps.SupportMapFragment;
    import com.google.android.gms.maps.model.LatLng;
    import com.google.android.gms.maps.model.MarkerOptions;
    
    public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    
    private static final int LOCATION_REQUEST_CODE = 101;
    private static final int LOCATION_REQUEST_CODE_2 = 102;
    //private   String  TAG = “MapDemo” ;
    private GoogleMap mMap;
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    
    protected void requestPermission() {
        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)
            {
                requestPermissions(new String[]{
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.ACCESS_FINE_LOCATION
                }, LOCATION_REQUEST_CODE);
            }
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case LOCATION_REQUEST_CODE: 
                if (grantResults.length == 0
                        || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Permission denied", Toast.LENGTH_LONG).show();
    
                break;
            }
    
        }
    }
    
    @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);
    
    }
    
    //@RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
    
        /*// Add a marker in Sydney, Australia, and move the camera.
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));*/
    
    
        if (mMap != null) {
            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);
    
                mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                // fetch location lat lng
    
            }
            else {
                requestPermission();
            }
    
        }
    }
    
    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Toast.makeText(this, "Online", Toast.LENGTH_SHORT).show();
    
    }
    
    @Override
    public void onConnectionSuspended(int i) {
    
    }
    
    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    
        }
    }