Получение текущего местоположения пользователя с помощью провайдера плавного определения местоположения

Я использую api местоположения службы google play (поставщик плавного определения местоположения), чтобы получить текущее местоположение пользователя. В некоторых случаях для возврата результатов требуется слишком много времени, а иногда для возврата результатов для того же устройства требуется гораздо меньше времени. В обоих случаях пользователь находился в помещении. Я не мог понять, в чем причина этого сценария.

public class SelfAttendanceFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
    OnMapReadyCallback, GoogleMap.OnMapClickListener {


protected static final int REQUEST_CHECK_SETTINGS = 0x1;
private static final int MY_PERMISSIONS_REQUEST = 1;
private static Double LATITUDE_DHAKA;
private static Double LONGITUDE_DHAKA;

LoadingDialog mLoadingDialog;
double latitude = 0;
double longitude = 0;
Handler mHandler;
CountDownTimer countDownTimer;
FusedLocationProviderClient mFusedLocationClient;
GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
LocationCallback mLocationCallback;
LocationManager locationManager;
SupportMapFragment mapFragment;
Location location;
private GoogleMap mMap;
private String address;
private String remarks = "";

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    View view = inflater.inflate(R.layout.fragment_self_attendance, container, false);
    ButterKnife.bind(this, view);
    return view;

}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    /*if (!checkPermissionGranted()) {
        askForPermission();
    }*/

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (getActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED

                && getActivity().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED ) {

            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION},
                    MY_PERMISSIONS_REQUEST);
        } else {
               startAction();
        }
    } else {
        startAction();
    }


}

private void startAction(){
    mLoadingDialog = new LoadingDialog(getContext(), getString(R.string.fetching_location));

    mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getContext());
    locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);

    doCheckPermissionForGps();

    mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            super.onLocationResult(locationResult);
            List<Location> locationList = locationResult.getLocations();
            for (Location loc : locationList) {
                if (loc.getLatitude() != 0 && loc.getLongitude() != 0) {
                    location = loc;
                    checkLocationandAddToMap();
                     break;
                }
            }

        }
    };
}


private void doCheckPermissionForGps() {

    Boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

    if (isGpsEnabled && mGoogleApiClient != null) {
        requestLocationUpdates();
    } else if (mGoogleApiClient == null) {
        buildGoogleApiClient();
    } else if (!isGpsEnabled) {
        displayLocationSettingsRequest(getContext());
    }

}

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

    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(10);
    mLocationRequest.setFastestInterval(10 / 2);
}

private String getAddressByLattitudeAndLongitude() {
    String address;
    try {
        Geocoder geocoder;
        List<Address> addresses;
        geocoder = new Geocoder(getContext(), Locale.getDefault());

        addresses = geocoder.getFromLocation(latitude, longitude, 5); // Here 1 represent max location result to returned, by documents it recommended 1 to 5

        address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
        if (address.isEmpty()) {
            address = addresses.get(0).getLocality();
        }
    } catch (Exception ex) {
        address = "";
    }
    return address;
}

private void displayLocationSettingsRequest(Context context) {
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
    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:
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    try {
                        status.startResolutionForResult(getActivity(), REQUEST_CHECK_SETTINGS);
                    } catch (IntentSender.SendIntentException e) {
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    break;
            }
        }
    });

}



 @SuppressLint("MissingPermission")
private void requestLocationUpdates() {
    if(isAdded() && getActivity() != null){
        mLoadingDialog.showDialogWithText("Fetching location using GPS...");
    }

    mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode,resultCode,data);
    switch (resultCode) {
        case -1:
            requestLocationUpdates();

            break;
        case 0:
            displayLocationSettingsRequest(getContext());
            break;
        default:
            super.onActivityResult(requestCode, resultCode, data);
            break;
    }


}

@Override
public void onConnected(@Nullable Bundle bundle) {
    if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        displayLocationSettingsRequest(getContext());
    } else {
        requestLocationUpdates();
    }
}

@Override
public void onConnectionSuspended(int i) {

}

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

}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mFusedLocationClient != null) {
        mFusedLocationClient.removeLocationUpdates(mLocationCallback);
    }
}

@SuppressLint("MissingPermission")
@Override
public void onMapReady(GoogleMap googleMap) {

    try{
        mMap = googleMap;
        mMap.clear();

        LATITUDE_DHAKA = 23.777176;
        LONGITUDE_DHAKA = 90.399452;
        try {

            boolean success = mMap.setMapStyle(
                    MapStyleOptions.loadRawResourceStyle(
                            getContext(), R.raw.style_map));


        } catch (Resources.NotFoundException e) {
            e.printStackTrace();
        }

        CameraPosition camPosition = new CameraPosition.Builder()
                .target(new LatLng(LATITUDE_DHAKA, LONGITUDE_DHAKA)).zoom(10)                   // Sets the zoom
                // Sets the orientation of the camera to east
                .build();

        if (mMap != null)
            mMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(camPosition));

        mMap.setMyLocationEnabled(true);
        mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
            @Override
            public boolean onMyLocationButtonClick() {
                doCheckPermissionForGps();
                return false;
            }
        });


        View locationButton = ((View) mapFragment.getView().findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                locationButton.getLayoutParams();
        // position on right bottom
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
        layoutParams.setMargins(0, 0, 0, 100);
    } catch (Exception ex){

    }



}

private void checkLocationandAddToMap() {

    //MarkerOptions are used to create a new Marker.You can specify location, title etc with MarkerOptions
    if (location != null) {

        CameraPosition camPosition = new CameraPosition.Builder()
                .target(new LatLng(location.getLatitude(), location.getLongitude())).zoom(17)                   // Sets the zoom
                // Sets the orientation of the camera to east
                .build();

        if (mMap != null)
            mMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(camPosition));

    }
}

@Override
public void onMapClick(LatLng latLng) {

}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                       int[] grantResults) {
    if (requestCode == MY_PERMISSIONS_REQUEST
            && grantResults[0] == PackageManager.PERMISSION_GRANTED

            && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
        startAction();
    } else {
        CustomSnackbarError.showMessageFromFragment(getContext(),"Permission is necessary" +
                " to enable this feature");
        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION},
                MY_PERMISSIONS_REQUEST);
    }
}

/*@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED
                    && grantResults[1] == PackageManager.PERMISSION_GRANTED
                   *//* && grantResults[2] == PackageManager.PERMISSION_GRANTED
                    && grantResults[3] == PackageManager.PERMISSION_GRANTED
                    && grantResults[4] == PackageManager.PERMISSION_GRANTED
                    && grantResults[5] == PackageManager.PERMISSION_GRANTED
                    && grantResults[6] == PackageManager.PERMISSION_GRANTED
                    && grantResults[7] == PackageManager.PERMISSION_GRANTED*//*
                    ) {

                //checkForUpdate();
                startAction();

            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}*/

private boolean checkPermissionGranted() {

  /*  if (ContextCompat.checkSelfPermission(getContext(),
            Manifest.permission.ACCESS_NETWORK_STATE)
            != PackageManager.PERMISSION_GRANTED) {
        return false;
    }

    if (ContextCompat.checkSelfPermission(getContext(),
            Manifest.permission.INTERNET)
            != PackageManager.PERMISSION_GRANTED) {
        return false;
    }*/

   /* if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.CALL_PHONE)
            != PackageManager.PERMISSION_GRANTED) {
        return false;
    }

    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {
        return false;
    }

    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        return false;
    }

    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        return false;
    }*/
    if (ContextCompat.checkSelfPermission(getContext(),
            Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        return false;
    }

    if (ContextCompat.checkSelfPermission(getContext(),
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        return false;
    }
    return true;
}

private void askForPermission() {

    ActivityCompat.requestPermissions((Activity) getContext(),
            new String[]{
                    /*Manifest.permission.ACCESS_NETWORK_STATE,
                    Manifest.permission.INTERNET,
                    Manifest.permission.CALL_PHONE,
                    Manifest.permission.CAMERA,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,*/
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,
            },
            MY_PERMISSIONS_REQUEST);
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    dismisLoadingDialog();
}
private void dismisLoadingDialog(){
    if(mLoadingDialog != null && mLoadingDialog.isShowing()){
        mLoadingDialog.dismiss();
    }
}

}


person Shadman Sakib    schedule 06.03.2019    source источник


Ответы (2)


Большую часть времени провайдеру GPS требуется много времени, чтобы определить местоположение, когда пользователь находится в здании. В этом случае вам необходимо получить местоположение от сетевого провайдера для более быстрых результатов. GPS работает очень хорошо за пределами здания, но не может определить местоположение внутри. Пожалуйста, разрешите получение местоположения как из сети, так и из GPS-провайдера для улучшения результата.

person Aman Srivastava    schedule 06.03.2019

То, как Android реализовал и создал эту библиотеку fusedlocationprovider, требует двух типов обновлений местоположения: 1 -> на основе сети 2 -> GPS

Например, когда пользователь пытается получить местоположение из помещения или любого другого места, где GPS не имеет достаточно места для получения местоположения со спутника, он использует сеть.

поэтому, когда вы работаете в помещении, вы увидите, что это беспокоит выбор местоположения. Но, как вы сказали, иногда это занимает меньше времени, а иногда требует много времени.

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

И вы использовали провайдера GPS, используйте также провайдера сети.

Дайте мне знать, если это поможет. Спасибо

person Karsh Soni    schedule 06.03.2019