Android LocationServices.FusedLocationApi kullanımdan kaldırıldı


89

LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest, this);"FusedLocationApi" nin neden üstü çizildiğini anlayamadım ve kullanımdan kaldırıldı ifadesini işaret ettim. Resmi görmek için buraya tıklayın

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) {

}
}

Kullanımdan kaldırılmışsa, bu satırda lütfen bu LocationServices.FusedLocationApi.requestLocationUpdates (mGoogleApiClient, mLocationRequest, this) kullanıyorum;
Omar Hayat

@OmarHayat FusedLocationApi çarpıyor
vvvv

bağımlılıklarınızı kontrol et Bu derlemeyi kullanarak derlediğim 'com.google.android.gms: play-services-location: 9.4.0'
Omar Hayat

Bunu oncreate metodunda kullanıyorsunuz mGoogleApiClient = new GoogleApiClient.Builder (this) .addApi (LocationServices.API) .addConnectionCallbacks (this) .addOnConnectionFailedListener (this) .build ();
Omar Hayat

@OmarHayat 'com.google.android.gms: play-services-location: 11.4.0' derlemesini kullanıyordum ve 9.4.0'a değiştirdikten sonra sorunu düzeltti, numarayı değiştirdikten sonra neden düzeldi?
vvvv

Yanıtlar:


156

Orijinal Cevap

Bu, FusedLocationProviderApigoogle play hizmetlerinin son sürümünde kullanımdan kaldırıldığı için oluyor . Buradan kontrol edebilirsiniz . Resmi kılavuz şimdi FusedLocationProviderClient kullanmayı öneriyor . Ayrıntılı kılavuzu burada bulabilirsiniz .

örneğin içinde onCreate()veya onViewCreated()bir FusedLocationProviderClientörnek oluştur

Kotlin

val fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireContext())

ve bilinen son konumu istemek için tek yapmanız gereken aramak

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

FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireContext());

ve

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
        }
    });

Basit, değil mi?


Önemli Güncelleme (24 Ekim 2017):

Dün Google, resmi geliştirici sayfasını şu şekilde bir uyarı ile güncelledi :

Lütfen FusedLocationProviderApi sınıfını kullanmaya devam edin ve 2018'in başlarında gönderilmesi beklenen Google Play hizmetleri 12.0.0 sürümü mevcut olana kadar FusedLocationProviderClient sınıfına geçiş yapmayın. 12.0.0'dan önce FusedLocationProviderClient kullanmak, Cihazda Google Play hizmetleri güncellenir. Bunun neden olabileceği rahatsızlıktan dolayı özür dileriz.

uyarı Bu nedenle, LocationServices.FusedLocationApiGoogle sorunu çözene kadar kullanımdan kaldırılanları kullanmaya devam etmemiz gerektiğini düşünüyorum .


Son Güncelleme (21 Kasım 2017):

Uyarı artık gitti. Google Play hizmetleri 11.6 6 Kasım 2017 sürüm notunda şunlar yazıyor: Google Play hizmetleri güncellendiğinde zaman zaman çökmelere neden olan FusedLocationProviderClient sorunu düzeltildi.Play Services'in arka planda kendini güncellediğinde çökmeyeceğini düşünüyorum. Artık yeniyi kullanabiliriz FusedLocationProviderClient.


3
Google dokümanlarının hala eski API'yi kullanmanızı söylemesine bayılıyorum: developer.android.com/training/location/…
mxcl

getLastLocation () LocationServices.FusedLocationApi.requestLocationUpdates () yaptığı şeyi yapıyor mu? Şimdiye kadar çok garip olan, belgelerin hala o eski yolu göstermesidir. Kafa karıştırıcı. developer.android.com/training/location/…
Juan Mendez

@JuanMendez Katılıyorum. Uygun güncel örnekleri sürdürmek için çalışmaları gerekir. btw getLastLocation()yalnızca cihazın bilinen en son konumunu döndürür .. yeni requestLocationUpdates(LocationRequest request, PendingIntent callbackIntent)yöntemle konum güncellemesi talep edebilirsiniz .
Somesh Kumar

@SomeshKumar, teşekkürler. evet, kullandığım yöntem bu. Bu arada 11.2.0'a bağlı kalıyorum.
Juan Mendez

2
@Fraid Evet, uyarı gitti .. ve sağladığınız bağlantı, kullanıcı uygulamayı güncellerse google play hizmetlerinin yeni sürümünün çökmeyeceğini de belirtiyor. Sanırım cevabımı şimdi güncellemeliyim.
Somesh Kumar

16
   // 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();
        }
    }

Ve fragment_location.xml dosyamız

       <?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>

bu satırı kaldırın. Ve kodun geri kalanı sizin için çalışacak
JoboFive

sonraki aralıkta konum
VY

@Vishal, manifestte ve kod içinde konum iznini kontrol etmeniz gereken her örnekte gerçek zamanlı konum alıyorum
JoboFive

Kodunuz için teşekkürler. Ama bir sorun var, her 100 metrede bir lokasyona ihtiyacım olursa ve sunucuya gönderirsem ne yapmalıyım? Lütfen yardım et.
Pravinsingh Waghela

Şunun gibi kullanın: locationRequest = LocationRequest.create () .setPriority (LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval (90000) .setSmallestDisplacement (10) .setFastestInterval (10000);
JoboFive


2

Evet, kullanımdan kaldırıldı!
Yeni FusedLocationProviderClient'i kullanırken ihtiyacınız olacak bazı noktalar .

  1. ithal olarak içe aktar com.google.android.gms.location.FusedLocationProviderClient;😅
  2. LocationListener arayüzünü uyguladığınızı fark ettim . MFusedLocationClient.requestLocationUpdates () yönteminde, artık parametre olarak LocationListener almıyor. LocationCallback sağlayabilirsiniz . Bu soyut bir sınıf olduğundan, onu LocationListener gibi uygulayamazsınız. Bir geri arama yöntemi yapın ve Google'ın kılavuzunda belirtildiği gibi 'bu' yerine bunu iletin . olarak içe aktarimport com.google.android.gms.location.LocationCallback;
  3. LocationCallback ile onLocationChanged () yerine onLocationResult () olacaktır . Location nesnesi yerine LocationResult nesnesini döndürür . Bu sonuç nesnesinde mevcut olan en son konumu almak için LocationResult.getLastLocation () kullanın. Olarak içe aktarimport com.google.android.gms.location.LocationResult;

2

Evet, kullanımdan kaldırıldı. FusedLocationProviderClientbundan daha kolaydır FusedLocationProviderApi, çünkü FusedLocationProviderApigenellikle manuel GoogleApiClientolarak bağlanmamız gereken çok gerektirir Google Play Service. Daha önce kullandıysanız GoogleApiClient, GoogleApiClientartık gerekli değildir ( daha fazlası burada ).

Son konumu almak için bu işlevi kullanabilirsiniz:

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());
                    }
                }
            });

}

-1

sorun ithalat beyanınızda

Bunu kaldır

import android.location.LocationListener;

Ekle

import com.google.android.gms.location.LocationListener;

-1

Lütfen Aktivitenizin Android işletim sisteminden değil Google Hizmetlerinden LocationListener uygulamasını gerçekleştirmesini sağlayın, bu benim için çalıştı.


-1

Bunun yerine getFusedLocationProviderClient kullanın 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) {
                // ...
            }
        });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.