Получить текущее местоположение пользователей при начальной загрузке приложения с помощью PlacesClient (но выдает ошибку APIException)

#java #android

Вопрос:

Я пытаюсь создать приложение, которое при первоначальной установке получает текущее местоположение пользователя и сохраняет его для последующего использования. Но это вызывает исключение APIException при начальной загрузке с помощью a statusCode of 8 .

Шаги по воспроизведению:

  1. Новая установка приложения, если приложение уже существует, удалите его/Очистите кэш и хранилище.
  2. Отключите расположение устройства перед установкой/открытием его снова после очистки кэша и хранилища.

*P.S. Было бы очень полезно, если бы существовал другой способ реализации получения текущего местоположения пользователя!

 private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_CHECK_SETTINGS = 99;

private PlacesClient placesClient;
TextView changeLocationStatus;
// Initializing the Places API with the API_KEY and creating the PlacesClient
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Places.initialize(getApplicationContext(), <INSERT_YOUR_GEO_LOCATION_API_KEY_HERE>);
    placesClient = Places.createClient(this);
    changeLocationStatus = (TextView) findViewById(R.id.change_location_status);
    if (hasLocationPermission()) {
        getCurrentLocationSettings();
    }
}


// To check whether the user gave the required permission to the application
private boolean hasLocationPermission() {
    try {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CHECK_SETTINGS);
            return false;
        } else {
            return true;
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "hasLocationPermission: Error checking permission!");
        return false;
    }
}

//  Turn on the device location if it is not already switched on using this prompt.
private void getCurrentLocationSettings() {
    LocationRequest mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
    SettingsClient client = LocationServices.getSettingsClient(this);
    Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
    task.addOnSuccessListener(locationSettingsResponse -> {
        LocationSettingsStates states = locationSettingsResponse.getLocationSettingsStates();
        if (states.isLocationPresent())
            getPossibleCurrentLocation();
    }).addOnFailureListener(e -> {
        if (e instanceof ResolvableApiException) {
            try {
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(this, REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException sendEx) {
                Log.d(TAG, "Error requesting settings change.");
            }
        }
    });
}

// Fetches the possible location and posts it to the TextView
@SuppressLint("DefaultLocale")
private void getPossibleCurrentLocations() {
    List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.ADDRESS, Place.Field.LAT_LNG);
    FindCurrentPlaceRequest request = FindCurrentPlaceRequest.newInstance(placeFields);
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
        return;
    Task<FindCurrentPlaceResponse> placeResponse = placesClient.findCurrentPlace(request);
    placeResponse.addOnSuccessListener(findCurrentPlaceResponse -> {
        try {
            PlaceLikelihood placeLikelihood = findCurrentPlaceResponse.getPlaceLikelihoods().get(0);
            changeLocationStatus.setText(String.format("Place '%s' with placeId '%s' has likelihood: %f",
                    placeLikelihood.getPlace().getName(),
                    placeLikelihood.getPlace().getId(),
                    placeLikelihood.getLikelihood()));
            String placeId = placeLikelihood.getPlace().getId();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }).addOnFailureListener(e -> {
        if (e instanceof ApiException) {
            ApiException apiException = (ApiException) e;
            Log.e(TAG, "Issue with getting the Location (status code): "   apiException.getStatusCode());
        }
    });
}

// onRequestPermissionResult - to check if it received the succes.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_CHECK_SETTINGS) {
        if (grantResults.length > 0 amp;amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            getCurrentLocationSettings();
        }
    }
}

// To check if the LocationServicesEnabled
private boolean isLocationServiceEnabled() {
    LocationManager lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    boolean gps_enabled = false;
    boolean network_enabled = false;
    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ignored) {
    }
    return gps_enabled || network_enabled;
}

// finally to get the result from the prompt if it is OK, then try getting the user's location again.
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CHECK_SETTINGS) {
        if (isLocationServiceEnabled()) {
            getCurrentLocationSettings();
        }
    }
}
 

Поэтому я думаю, что проблема может быть в задержке с location включением и требуемой функцией, которая его вызывает!?

Попытается ли создать thread и перевести его в спящий режим и снова вызовет требуемую функцию?

Комментарии:

1. Хм, прямо сейчас я решил эту проблему хакерским способом, неоднократно вызывая getPossibleCurrentLocation, по крайней мере, с 5 попыток.