Я не мог понять, почему LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest, this);
«FusedLocationApi» зачеркнуто и указывает на то, что он устарел.
Щелкните здесь, чтобы просмотреть изображение
import android.location.Location;
import android.location.LocationListener;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MaintainerMapActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener{
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocaton;
LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maintainer_map2);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onConnected(@Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
}
Ответы:
Оригинальный ответ
Это происходит из-за того, что эта функция
FusedLocationProviderApi
устарела в последней версии сервисов Google Play. Вы можете проверить это здесь . Официальное руководство теперь предлагает использовать FusedLocationProviderClient . Вы можете найти подробное руководство здесь .например, внутри
onCreate()
илиonViewCreated()
создатьFusedLocationProviderClient
экземплярКотлин
и для запроса последнего известного местоположения все, что вам нужно сделать, это позвонить
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? -> location?.let { it: Location -> // Logic to handle location object } ?: kotlin.run { // Handle Null case or Request periodic location update https://developer.android.com/training/location/receive-location-updates } }
Ява
а также
fusedLocationClient.getLastLocation().addOnSuccessListener(requireActivity(), location -> { if (location != null) { // Logic to handle location object } else { // Handle null case or Request periodic location update https://developer.android.com/training/location/receive-location-updates } });
Просто, не правда ли?
Важное обновление (24 октября 2017 г.):
Вчера Google обновил свою официальную страницу разработчика с предупреждением, в котором говорится:
Поэтому я думаю, что мы должны продолжать использовать устаревшее,
LocationServices.FusedLocationApi
пока Google не решит проблему.Последнее обновление (21 ноября 2017 г.):
Предупреждение исчезло. Сервисы Google Play 11.6 6 ноября 2017 г., в примечании к выпуску говорится: « Я думаю, что сервисы Play не будут давать сбоев при обновлении в фоновом режиме. Так что
FusedLocationProviderClient
теперь мы можем использовать новое .источник
getLastLocation()
возвращать только самое последнее известное местоположение устройства .. вы можете запросить обновление местоположения с помощью новогоrequestLocationUpdates(LocationRequest request, PendingIntent callbackIntent)
метода.// Better to use GoogleApiClient to show device location. I am using this way in my aap. public class SuccessFragment extends Fragment{ private TextView txtLatitude, txtLongitude, txtAddress; // private AddressResultReceiver mResultReceiver; // removed here because cause wrong code when implemented and // its not necessary like the author says //Define fields for Google API Client private FusedLocationProviderClient mFusedLocationClient; private Location lastLocation; private LocationRequest locationRequest; private LocationCallback mLocationCallback; private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 14; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_location, container, false); txtLatitude = (TextView) view.findViewById(R.id.txtLatitude); txtLongitude = (TextView) view.findViewById(R.id.txtLongitude); txtAddress = (TextView) view.findViewById(R.id.txtAddress); // mResultReceiver = new AddressResultReceiver(null); // cemented as above explained try { mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity()); mFusedLocationClient.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) { // Logic to handle location object txtLatitude.setText(String.valueOf(location.getLatitude())); txtLongitude.setText(String.valueOf(location.getLongitude())); if (mResultReceiver != null) txtAddress.setText(mResultReceiver.getAddress()); } } }); locationRequest = LocationRequest.create(); locationRequest.setInterval(5000); locationRequest.setFastestInterval(1000); if (txtAddress.getText().toString().equals("")) locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); else locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { for (Location location : locationResult.getLocations()) { // Update UI with location data txtLatitude.setText(String.valueOf(location.getLatitude())); txtLongitude.setText(String.valueOf(location.getLongitude())); } } ; }; } catch (SecurityException ex) { ex.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return view; } @Override public void onStart() { super.onStart(); if (!checkPermissions()) { startLocationUpdates(); requestPermissions(); } else { getLastLocation(); startLocationUpdates(); } } @Override public void onPause() { stopLocationUpdates(); super.onPause(); } /** * Return the current state of the permissions needed. */ private boolean checkPermissions() { int permissionState = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION); return permissionState == PackageManager.PERMISSION_GRANTED; } private void startLocationPermissionRequest() { ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_PERMISSIONS_REQUEST_CODE); } private void requestPermissions() { boolean shouldProvideRationale = ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION); // Provide an additional rationale to the user. This would happen if the user denied the // request previously, but didn't check the "Don't ask again" checkbox. if (shouldProvideRationale) { Log.i(TAG, "Displaying permission rationale to provide additional context."); showSnackbar(R.string.permission_rationale, android.R.string.ok, new View.OnClickListener() { @Override public void onClick(View view) { // Request permission startLocationPermissionRequest(); } }); } else { Log.i(TAG, "Requesting permission"); // Request permission. It's possible this can be auto answered if device policy // sets the permission in a given state or the user denied the permission // previously and checked "Never ask again". startLocationPermissionRequest(); } } /** * Callback received when a permissions request has been completed. */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { Log.i(TAG, "onRequestPermissionResult"); if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) { if (grantResults.length <= 0) { // If user interaction was interrupted, the permission request is cancelled and you // receive empty arrays. Log.i(TAG, "User interaction was cancelled."); } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission granted. getLastLocation(); } else { // Permission denied. // Notify the user via a SnackBar that they have rejected a core permission for the // app, which makes the Activity useless. In a real app, core permissions would // typically be best requested during a welcome-screen flow. // Additionally, it is important to remember that a permission might have been // rejected without asking the user for permission (device policy or "Never ask // again" prompts). Therefore, a user interface affordance is typically implemented // when permissions are denied. Otherwise, your app could appear unresponsive to // touches or interactions which have required permissions. showSnackbar(R.string.permission_denied_explanation, R.string.settings, new View.OnClickListener() { @Override public void onClick(View view) { // Build intent that displays the App settings screen. Intent intent = new Intent(); intent.setAction( Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null); intent.setData(uri); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }); } } } /** * Provides a simple way of getting a device's location and is well suited for * applications that do not require a fine-grained location and that do not need location * updates. Gets the best and most recent location currently available, which may be null * in rare cases when a location is not available. * <p> * Note: this method should be called after location permission has been granted. */ @SuppressWarnings("MissingPermission") private void getLastLocation() { mFusedLocationClient.getLastLocation() .addOnCompleteListener(getActivity(), new OnCompleteListener<Location>() { @Override public void onComplete(@NonNull Task<Location> task) { if (task.isSuccessful() && task.getResult() != null) { lastLocation = task.getResult(); txtLatitude.setText(String.valueOf(lastLocation.getLatitude())); txtLongitude.setText(String.valueOf(lastLocation.getLongitude())); } else { Log.w(TAG, "getLastLocation:exception", task.getException()); showSnackbar(getString(R.string.no_location_detected)); } } }); } private void stopLocationUpdates() { mFusedLocationClient.removeLocationUpdates(mLocationCallback); } private void startLocationUpdates() { if (ActivityCompat.checkSelfPermission(getActivity(), 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; } mFusedLocationClient.requestLocationUpdates(locationRequest, mLocationCallback, null); } // private void showSnackbar(final String text) { // if (canvasLayout != null) { // Snackbar.make(canvasLayout, text, Snackbar.LENGTH_LONG).show(); // } //} // this also cause wrong code and as I see it dont is necessary // because the same method which is really used private void showSnackbar(final int mainTextStringId, final int actionStringId, View.OnClickListener listener) { Snackbar.make(getActivity().findViewById(android.R.id.content), getString(mainTextStringId), Snackbar.LENGTH_INDEFINITE) .setAction(getString(actionStringId), listener).show(); } }
И наш fragment_location.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/locationLayout" android:layout_below="@+id/txtAddress" android:layout_width="match_parent" android:layout_height="@dimen/activity_margin_30dp" android:orientation="horizontal"> <TextView android:id="@+id/txtLatitude" android:layout_width="@dimen/activity_margin_0dp" android:layout_height="@dimen/activity_margin_30dp" android:layout_weight="0.5" android:gravity="center" android:hint="@string/latitude" android:textAllCaps="false" android:textColorHint="@color/colorPrimaryDark" android:textColor="@color/colorPrimaryDark" /> <TextView android:id="@+id/txtLongitude" android:layout_width="@dimen/activity_margin_0dp" android:layout_height="@dimen/activity_margin_30dp" android:layout_weight="0.5" android:gravity="center" android:hint="@string/longitude" android:textAllCaps="false" android:textColorHint="@color/colorPrimary" android:textColor="@color/colorPrimary" /> </LinearLayout>
источник
Используйте этот метод
Подробнее см. Мой ответ
источник
Да, это не рекомендуется!
Вот некоторые моменты, которые вам понадобятся при использовании нового FusedLocationProviderClient .
com.google.android.gms.location.FusedLocationProviderClient;
😅import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationResult;
источник
Да, он устарел.
FusedLocationProviderClient
проще, чемFusedLocationProviderApi
, потому чтоFusedLocationProviderApi
обычно также требуетGoogleApiClient
, к которому нам нужно подключитьсяGoogle Play Service
вручную. Если раньше использовалиGoogleApiClient
, то сейчасGoogleApiClient
больше не нужны ( подробнее здесь ).Чтобы получить последнее местоположение, можно использовать эту функцию:
import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.tasks.OnCompleteListener; public class MainActivity extends AppCompatActivity{ //before public class MainActivity extends AppCompatActivity implements LocationListener,...,... private static final String TAG = "MainActivity"; public static final int MY_PERMISSIONS_REQUEST_FINE_LOCATION = 101; private FusedLocationProviderClient mFusedLocationClient; private Location mGetedLocation; private double currentLat, currentLng; private void getLastLocation() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_FINE_LOCATION); } return; } mFusedLocationClient.getLastLocation() .addOnCompleteListener(this, new OnCompleteListener<Location>() { @Override public void onComplete(@NonNull Task<Location> task) { if (task.isSuccessful() && task.getResult() != null) { mGetedLocation = task.getResult(); currentLat = mGetedLocation.getLatitude(); currentLng = mGetedLocation.getLongitude(); //updateUI(); }else{ Log.e(TAG, "no location detected"); Log.w(TAG, "getLastLocation:exception", task.getException()); } } }); }
источник
проблема с вашим оператором импорта
удали это
import android.location.LocationListener;
Добавить
import com.google.android.gms.location.LocationListener;
источник
Пожалуйста, сделайте свою Activity реализуемой LocationListener из служб Google, а не из ОС Android, это сработало для меня.
источник
используйте getFusedLocationProviderClient вместо LocationServices.FusedLocationApi.
Котлин
activity?.let { activity -> val client = LocationServices.getFusedLocationProviderClient(activity) client.lastLocation.addOnCompleteListener(activity, OnCompleteListener<Location> { // it.result.latitude // it.result.longitude }) }
Ява
FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this); // Get the last known location client.getLastLocation() .addOnCompleteListener(this, new OnCompleteListener<Location>() { @Override public void onComplete(@NonNull Task<Location> task) { // ... } });
источник