我正在使用Google Play服务位置api(融合的位置提供程序)来获取用户当前位置。在某些情况下,返回结果花费的时间太多,有时返回同一设备的结果需要花费的时间更少。在这两种情况下,用户都在室内。我不明白这是造成这种情况的原因。
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();
}
}
}
答案 0 :(得分:0)
大多数时候,当用户在建筑物内时,GPS提供商会花费大量时间来获取位置。在这种情况下,您必须从网络提供商处获取位置以获得更快的结果。 GPS在建筑物外部工作得很好,但是很难从内部获取位置。请允许从网络和GPS提供商处获取位置,以改善结果。
答案 1 :(得分:0)
android实现和创建此fusedlocationprovider库的方式是它需要两种类型的位置更新: 1->基于网络 2-> GPS
当用户尝试从室内或GPS没有足够空间从卫星获取位置的任何地方获取位置时,它会使用网络。
因此,当您在室内工作时,您会发现它在困扰获取位置。但是正如您所说,有时会花费更少的时间,有时会花费很多时间。
可能的情况是,无论何时您请求位置,它都会去尝试查找该位置(如果其他应用程序已经使用该位置),并且如果有位置,您将得到它。否则,它将尝试自行查找位置,并且下次您已经搜索到该位置时,它将直接为您提供搜索。
您已经使用了GPS提供程序,也使用了网络提供程序。
让我知道是否有帮助。谢谢