Je ne pouvais pas comprendre pourquoi LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest, this);
"FusedLocationApi" est barré et le pointer en disant qu'il est obsolète.
Cliquez ici pour voir l'image
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) {
}
}
Réponses:
Réponse originale
Cela se produit car
FusedLocationProviderApi
obsolète dans une version récente des services Google Play. Vous pouvez le vérifier ici . Le guide officiel suggère maintenant d'utiliser FusedLocationProviderClient . Vous pouvez trouver le guide détaillé ici .par exemple à l'intérieur
onCreate()
ouonViewCreated()
créer uneFusedLocationProviderClient
instanceKotlin
et pour demander le dernier emplacement connu, tout ce que vous avez à faire est d'appeler
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 } }
Java
et
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 } });
Simple, n'est-ce pas?
Mise à jour importante (24 octobre 2017):
Hier, Google a mis à jour sa page officielle de développeur avec un avertissement indiquant
Je pense donc que nous devrions continuer à utiliser la version obsolète
LocationServices.FusedLocationApi
jusqu'à ce que Google résolve le problème.Dernière mise à jour (21 novembre 2017):
L'avertissement est parti maintenant. Services Google Play 11.6 Le 6 novembre 2017, la note de publication indique: Je pense que les services Play ne planteront pas lorsqu'ils se mettront à jour en arrière-plan. Nous pouvons donc utiliser de nouvelles dès
FusedLocationProviderClient
maintenant.la source
getLastLocation()
ne renvoie que l'emplacement connu le plus récent de l'appareil .. vous pouvez demander la mise à jour de l'emplacement avec une nouvellerequestLocationUpdates(LocationRequest request, PendingIntent callbackIntent)
méthode.// 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(); } }
Et notre 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>
la source
Utilisez cette méthode
En détail, référez-moi à cette réponse
la source
Oui, c'est obsolète!
Voici quelques points dont vous aurez besoin lors de l'utilisation du nouveau FusedLocationProviderClient .
com.google.android.gms.location.FusedLocationProviderClient;
😅import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationResult;
la source
Oui, il est obsolète.
FusedLocationProviderClient
est plus facile queFusedLocationProviderApi
, car il enFusedLocationProviderApi
faut généralementGoogleApiClient
trop, auquel nous devons nous connecterGoogle Play Service
manuellement. Si vous avez déjà utiliséGoogleApiClient
, maintenantGoogleApiClient
n'est plus nécessaire ( plus ici ).Pour obtenir le dernier emplacement, vous pouvez utiliser cette fonction:
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()); } } }); }
la source
le problème vient de votre déclaration d'importation
enlève ça
import android.location.LocationListener;
ajouter
import com.google.android.gms.location.LocationListener;
la source
Veuillez faire en sorte que votre activité implémente LocationListener à partir des services Google et non du système d'exploitation Android, cela a fonctionné pour moi.
la source
utilisez plutôt getFusedLocationProviderClient LocationServices.FusedLocationApi.
Kotlin
activity?.let { activity -> val client = LocationServices.getFusedLocationProviderClient(activity) client.lastLocation.addOnCompleteListener(activity, OnCompleteListener<Location> { // it.result.latitude // it.result.longitude }) }
Java
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) { // ... } });
la source