Как получить текущее местоположение пользователя в Android

Я хочу, чтобы пользовательский текущий lat был нажат одним нажатием кнопки. Я знаю, что вы можете получить последнее известное местоположение, используя FusedLocationApi. Но то, что я не могу понять, должно быть включено для службы gps или определения местоположения? Если да, то как проверить, что пользователь включил местоположение и получить текущее местоположение. Кроме того, как включить проверки разрешений маршала в получении местоположения.

Я уже говорил: 1) googlesamples/android-play-location 2) googlesamples/android-XYZTouristAttractions и многие другие ссылки, но неспособные сделать полный поток.

код

public class AccessLocationFragment extends BaseFragment implements View.OnClickListener, LocationListener,
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, GeneralDialogFragment.GeneralDialogClickListener {

private static final int MY_PERMISSIONS_REQUEST_LOCATION = 101;
private static final String TAG = AccessLocationFragment.class.getSimpleName();
private static final int REQUEST_CHECK_SETTINGS = 102;
private Button mAccessLocation;
private EditText mZipCode;
private Dialog progressDialog;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;

public static AccessLocationFragment newInstance() {
    return new AccessLocationFragment();
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_access_location, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    RecycleApplication.getEventBus().register(this);
    mAccessLocation = (Button) view.findViewById(R.id.access_location);
    mZipCode = (EditText) view.findViewById(R.id.zip_code);
    mAccessLocation.setOnClickListener(this);

    mZipCode.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                String zipCode = mZipCode.getText().toString().trim();
                if (TextUtils.isEmpty(zipCode)) {
                    Toast.makeText(mActivity, "Please enter zip code", Toast.LENGTH_SHORT).show();
                } else {
                    Call<Address> response = mRecycleService.getAddress(zipCode);
                    response.enqueue(new GetLocationCallback(AccessLocationFragment.this));
                }
            }
            return false;
        }
    });
    // Create an instance of GoogleAPIClient.
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
    if (!LocationUtils.checkFineLocationPermission(mActivity)) {
        // See if user has denied permission in the past
        if (shouldShowRequestPermissionRationale(android.Manifest.permission.ACCESS_FINE_LOCATION)) {
            // Show a simple snackbar explaining the request instead
            showPermissionSnackbar();
        } else {
            requestFineLocationPermission();
        }
    } else {
        displayLocationSettingsRequest();
    }
}

private void startHomeActivity(Address address) {
    RecyclePreferences.getInstance().setCity(address.getCity());
    RecyclePreferences.getInstance().setState(address.getState());
    RecyclePreferences.getInstance().setLatitude(address.getLatitude());
    RecyclePreferences.getInstance().setLongitude(address.getLongitude());
    RecyclePreferences.getInstance().setZipCode(address.getZipCode());
    startActivity(new Intent(mActivity, HomeActivity.class));
    mActivity.finish();
}

@Override
public void onSuccess(Call<Address> call, Response<Address> response) {
    mActivity.hideProgressDialog(progressDialog);
    if (response.isSuccessful()) {
        Address address = response.body();
        startHomeActivity(address);
    }
}

@Override
public void onFailure(Call<Address> call, Throwable t) {
    mActivity.hideProgressDialog(progressDialog);
}

@Override
public void onClick(View view) {
    if (view.getId() == R.id.access_location) {
        fetchAddress(mLastLocation);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               displayLocationSettingsRequest();
            }
        }
    }
}

private void fetchAddress(Location location) {
    mRecycleService = new RecycleRetrofitBuilder(mActivity).getService();
    Call<Address> response = mRecycleService.getAddress(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
    progressDialog = mActivity.showProgressDialog(mActivity);
    response.enqueue(new GetLocationCallback(AccessLocationFragment.this));
}

private void requestFineLocationPermission() {
    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
}

private void showPermissionSnackbar() {
    GeneralDialogFragment generalDialogFragment = GeneralDialogFragment.
            newInstance("Permissions", "Allow Recycle the World to use your location.", "Allow", "Go Back", this);
    mActivity.showDialogFragment(generalDialogFragment);
    displayLocationSettingsRequest();
}

private void displayLocationSettingsRequest() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(10000);
    locationRequest.setFastestInterval(10000 / 2);

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
    builder.setAlwaysShow(true);

    PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    getLocation();
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
                    try {
                        status.startResolutionForResult(mActivity, REQUEST_CHECK_SETTINGS);
                    } catch (IntentSender.SendIntentException e) {
                        Log.i(TAG, "PendingIntent unable to execute request.");
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.");
                    break;
            }
        }
    });
}

private void getLocation() {
    if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CHECK_SETTINGS) {
        getLocation();
    }
}

@Override
public void onStart() {
    mGoogleApiClient.connect();
    super.onStart();
}

@Override
public void onStop() {
    mGoogleApiClient.disconnect();
    super.onStop();
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    getLocation();
}

@Override
public void onDestroy() {
    super.onDestroy();
    RecycleApplication.getEventBus().unregister(this);
}


@Override
public void onConnectionSuspended(int i) {

}

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

}

@Override
public void onOk(DialogFragment dialogFragment) {
    dialogFragment.dismiss();
    requestFineLocationPermission();
}

@Override
public void onCancel(DialogFragment dialogFragment) {
    dialogFragment.dismiss();

}

}

Ответ 1

Извините, я не просматриваю ваш код, я просто пишу функции, которые вы просили в своем вопросе. Во-первых, вам нужно создать соединение с клиентом google api, например:

private synchronized void buildGoogleApiClient(){
    mGoogleApiClient = new GoogleApiClient.Builder(GTApplication.getContext())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
}

После этого в моем опыте почти всегда вызывается функция onConnected(), где вы можете запросить разрешение на размещение после уровня API 23:

public void checkLocationPermission(){
    if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        // You don't have the permission you need to request it 
        ActivityCompat.requestPermissions(this, Manifest.permission.ACCESS_FINE_LOCATION), REQ_CODE);
    }else{
        // You have the permission.
        requestLocationAccess();
    }
}

Если вы запросили разрешение, ваша функция onRequestPermissionsResult() будет вызвана с помощью REQ_CODE. Если вам нужна дополнительная информация для реализации событий, проверьте оригинальную документацию для разрешений времени выполнения, это очень полезно.
Когда у вас есть разрешение, вы можете проверить, включено ли местоположение, например:

public void requestLocationAccess(){
    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval((long) (LocationHelper.UPDATE_INTERVAL_IN_MILLISECONDS*1.1));
    mLocationRequest.setFastestInterval(LocationHelper.UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    final LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
    builder.setAlwaysShow(true); //this is the key ingredient
    com.google.android.gms.common.api.PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>(){
        @Override
        public void onResult(@NonNull LocationSettingsResult result){
            if(requester != null){
                final Status resultStatus = result.getStatus();
                switch(resultStatus.getStatusCode()){
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. You can ask for the user location HERE



                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user a dialog.
                        try{
                            resultStatus.startResolutionForResult(this, REQUEST_LOCATION);
                            break;
                        }catch(IntentSender.SendIntentException ignored){}
                    }
                }
            }
        }
    });  
}

Если диалоговое окно разрешения местоположения необходимо показать пользователю, вы получите обратный вызов в onActivityResult() с кодом запроса REQUEST_LOCATION)

Чтобы после того, как вы сделали все это, вы можете позвонить locationManager.getLastKnownLocation() или начать запрос на размещение или что угодно.

PS: Я вырезал этот код из своего более крупного класса, поэтому, пожалуйста, если вы обнаружите ошибки, не стесняйтесь спрашивать. Я указал только на случай, когда все идет хорошо, потому что оно содержит суть, вы можете справиться с исключениями, я надеюсь.

Ответ 2

попробуйте этот код:

public void showMap() {

    mapFragment = (SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map);
    if (map == null) {
        map = mapFragment.getMap();
    }


    // Enable Zoom
    map.getUiSettings().setZoomGesturesEnabled(true);

    //set Map TYPE
    map.setMapType(GoogleMap.MAP_TYPE_NORMAL);

    //enable Current location Button
    map.setMyLocationEnabled(true);

    LocationManager locationManager = (LocationManager)getActivity().getSystemService(getActivity().LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    String bestProvider = locationManager.getBestProvider(criteria, true);
    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    Location location = locationManager.getLastKnownLocation(bestProvider);
    if (location != null) {
        onLocationChanged(location);
    }
    locationManager.requestLocationUpdates(bestProvider, 2000, 0, this);
}

@Override
public void onLocationChanged(Location location) {

    latitude= location.getLatitude();
    longitude=location.getLongitude();

    LatLng loc = new LatLng(latitude, longitude);

     if (marker!=null){
         marker.remove();
     }

    marker=  map.addMarker(new MarkerOptions().position(loc).title("Sparx IT Solutions"));
    map.moveCamera(CameraUpdateFactory.newLatLng(loc));
    map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));

}

@Override
public void onProviderDisabled(String provider) {

    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    startActivity(intent);
    Toast.makeText(getActivity().getBaseContext(), "Gps is turned off!!",
            Toast.LENGTH_SHORT).show();
}

@Override
public void onProviderEnabled(String provider) {

    Toast.makeText(getActivity().getBaseContext(), "Gps is turned on!! ",
            Toast.LENGTH_SHORT).show();
}