hi everyone i'm trying to get the user's location, but when i ask for permissions google maps doesn't load. Specifically I have this error:
2022-07-03 12:46:39.032 12031-12031/com.example.progetto E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.progetto, PID: 12031
java.lang.SecurityException: my location requires permission ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION
at com.google.maps.api.android.lib6.impl.bj.J(:com.google.android.gms.dynamite_mapsdynamite@[email protected] (100700-0):10)
at com.google.android.gms.maps.internal.i.ba(:com.google.android.gms.dynamite_mapsdynamite@[email protected] (100700-0):172)
at et.onTransact(:com.google.android.gms.dynamite_mapsdynamite@[email protected] (100700-0):4)
at android.os.Binder.transact(Binder.java:914)
at com.google.android.gms.internal.maps.zza.zzc(com.google.android.gms:play-services-maps@@18.0.0:2)
at com.google.android.gms.maps.internal.zzg.setMyLocationEnabled(com.google.android.gms:play-services-maps@@18.0.0:3)
at com.google.android.gms.maps.GoogleMap.setMyLocationEnabled(com.google.android.gms:play-services-maps@@18.0.0:1)
at com.example.progetto.MapsLine.onMapReady(MapsLine.java:207)
at com.google.android.gms.maps.zzat.zzb(com.google.android.gms:play-services-maps@@18.0.0:1)
at com.google.android.gms.maps.internal.zzaq.zza(com.google.android.gms:play-services-maps@@18.0.0:5)
at com.google.android.gms.internal.maps.zzb.onTransact(com.google.android.gms:play-services-maps@@18.0.0:3)
at android.os.Binder.transact(Binder.java:914)
at es.bc(:com.google.android.gms.dynamite_mapsdynamite@[email protected] (100700-0):2)
at com.google.maps.api.android.lib6.impl.bf.run(:com.google.android.gms.dynamite_mapsdynamite@[email protected] (100700-0):1)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
My code is:
public class MapsLine extends Fragment implements OnMapReadyCallback {
private static final int MY_PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 0;
private FusedLocationProviderClient fusedLocationClient;
private LocationCallback locationCallback;
private boolean requestingLocationUpdates = true;
GoogleMap gMap;
double latitude;
double longitude;
@Override
public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_maps_line, container, false);
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment supportMapFragment = (SupportMapFragment)
getChildFragmentManager().findFragmentById(R.id.map);
supportMapFragment.getMapAsync(this);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("MainActivity", "onCreate");
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
//callback per gli aggiornamenti di posizione
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
Log.d("main_activiyt_maps", "location request is null");
return;
}
//aggiorno i dati nelle textView con le informazioni della posizione aggiornata
for (Location location : locationResult.getLocations()) {
Log.d("Location", "New Location received: " location.toString());
latitude = location.getLatitude();
longitude=location.getLongitude();
Log.d("main_activiyt_maps", String.valueOf(latitude));
Log.d("main_activiyt_maps", String.valueOf(longitude));
}
}
};
}
@Override
public void onPause() {
super.onPause();
fusedLocationClient.removeLocationUpdates(locationCallback);
requestingLocationUpdates = false;
}
@Override
public void onResume() {
super.onResume();
Log.d("MainActivity", "onResume");
if (checkLocationPermission()) {
Log.d("MainActivity", "Permessi OK");
//richiedo l'ultima posizione
//richiedo aggiornamenti sulla posizione
startLocationUpdates();
}
}
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//ho i permessi, scrivo nella casella di testo che va tutto bene
Log.d("Location", "The permission is granted");
return true;
} else {
//non ho i permessi, devo richiederli
Log.d("Location", "Ask for permission");
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_REQUEST_ACCESS_FINE_LOCATION);
return false;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
Log.d("Location", "Now the permission is granted");
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
} else {
// permission was not granted
Log.d("Location", "Permission still not granted");
}
break;
}
}
}
public void getLastKnownLocation() {
if (checkLocationPermission()) {
fusedLocationClient.getLastLocation()
.addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
Log.d("Location", "Last known location:" location.toString());
} else {
Log.d("Location", "Last Known location not available");
}
}
});
}
}
//per chiedere la posizione aggiornata
private void startLocationUpdates() {
if (checkLocationPermission()) {
requestingLocationUpdates = true;
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(1000); //in ms.
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
}
}
@SuppressLint("MissingPermission")
@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
gMap = googleMap;
gMap.setMyLocationEnabled(true);
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(latitude,longitude);
gMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
gMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
gMap.clear(); //clear old markers
}
}
My themanifest code is:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="my_key" ></meta-data>
in the manifest I have ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION and in the code I check the permissions(checkLocationPermission()). why does it crash at the first start, when the app asks me for permissions?
CodePudding user response:
In onViewCreated()
, you are setting up your SupportMapFragment
. In onMapReady()
, you are trying to use location information via gMap.setMyLocationEnabled(true);
. Do not call setMyLocationEnabled()
until the user grants you permission.