Java Android LocationServices.FusedLocationApi 已弃用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46481789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android LocationServices.FusedLocationApi deprecated
提问by vvvv
I couldn't figure out why LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest, this);
"FusedLocationApi" is cross out and point at it saying is deprecated.
Click here to view Image
我无法弄清楚为什么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) {
}
}
采纳答案by Somesh Kumar
Original Answer
原答案
This is happening because FusedLocationProviderApi
deprecated in a recent version of google play services. You can check it here. The official guide now suggests using FusedLocationProviderClient. You can find the detailed guide here.
发生这种情况是因为FusedLocationProviderApi
最近版本的 google play 服务已弃用。你可以在这里查看。官方指南现在建议使用FusedLocationProviderClient。您可以在此处找到详细指南 。
for e.g inside onCreate()
or onViewCreated()
create a FusedLocationProviderClient
instance
例如在内部onCreate()
或onViewCreated()
创建一个FusedLocationProviderClient
实例
Kotlin
科特林
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireContext())
and for requesting the last known location all you have to do is call
并且要请求最后一个已知位置,您所要做的就是致电
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());
and
和
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, Isn't it?
很简单,不是吗?
Important Update (October 24, 2017):
重要更新(2017 年 10 月 24 日):
Yesterday Google updated its official developer page with a warningthat says
昨天谷歌更新了它的官方开发者页面,警告说
Please continue using the FusedLocationProviderApi class and don't migrate to the FusedLocationProviderClient class until Google Play services version 12.0.0 is available, which is expected to ship in early 2018. Using the FusedLocationProviderClient before version 12.0.0 causes the client app to crash when Google Play services is updated on the device. We apologize for any inconvenience this may have caused.
请继续使用 FusedLocationProviderApi 类,在 Google Play 服务版本 12.0.0 可用之前不要迁移到 FusedLocationProviderClient 类,该版本预计将于 2018 年初发布。在版本 12.0.0 之前使用 FusedLocationProviderClient 会导致客户端应用程序崩溃设备上的 Google Play 服务已更新。对此造成的任何不便,我们深表歉意。
So I think we should continue using the deprecated
LocationServices.FusedLocationApi
until Google resolves the issue.
所以我认为我们应该继续使用弃用的,
LocationServices.FusedLocationApi
直到谷歌解决这个问题。
Latest Update (November 21, 2017):
最新更新(2017 年 11 月 21 日):
The warning is gone now.Google Play services 11.6 November 6, 2017, release notesays : I think Play Services won't crash when it updates itself in the background. So we can use new
FusedLocationProviderClient
now.
现在警告消失了。Google Play 服务 11.6 2017 年 11 月 6 日,发行说明说:我认为 Play 服务在后台更新时不会崩溃。所以我们
FusedLocationProviderClient
现在可以使用new了。
回答by Malith
Yes, it's deprecated!
Here are some points you'll need while using new FusedLocationProviderClient.
是的,已弃用!
以下是您在使用新的FusedLocationProviderClient 时需要的一些要点。
- import it as import
com.google.android.gms.location.FusedLocationProviderClient;
- I notice that you are implementing LocationListenerinterface. In the mFusedLocationClient.requestLocationUpdates() method, now it doesn't take a LocationListener as a parameter. You can provide LocationCallback. As this is an abstract class you can't implement it like LocationListener. Make a callback method and pass it instead of 'this' as mentioned in Google's guide. import it as
import com.google.android.gms.location.LocationCallback;
- With LocationCallback, you'll have onLocationResult()instead of onLocationChanged(). It returns LocationResultobject instead of Location object. Use LocationResult.getLastLocation() to get the most recent location available in this result object. Import it as
import com.google.android.gms.location.LocationResult;
- 将其导入为导入
com.google.android.gms.location.FusedLocationProviderClient;
- 我注意到您正在实现LocationListener接口。在 mFusedLocationClient.requestLocationUpdates() 方法中,现在它不接受 LocationListener 作为参数。您可以提供LocationCallback。由于这是一个抽象类,您不能像 LocationListener 一样实现它。制作一个回调方法并传递它而不是谷歌指南中提到的“this” 。将其导入为
import com.google.android.gms.location.LocationCallback;
- 使用 LocationCallback,您将拥有onLocationResult()而不是onLocationChanged()。它返回LocationResult对象而不是 Location 对象。使用 LocationResult.getLastLocation() 获取此结果对象中可用的最新位置。将其导入为
import com.google.android.gms.location.LocationResult;
回答by JoboFive
// 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();
}
}
And our fragment_location.xml
还有我们的 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>
回答by dx arout
problem is with your import statement
问题在于您的导入语句
remove this
删除这个
import android.location.LocationListener;
add
添加
import com.google.android.gms.location.LocationListener;
回答by Karim Elbahi
Please make your Activity implement LocationListener from Google Services , not from Android OS?, this worked for me.
请让您的 Activity 从 Google Services 实现 LocationListener ,而不是从 Android OS? ,这对我有用。
回答by Rasoul Miri
use getFusedLocationProviderClient instead LocationServices.FusedLocationApi.
使用 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) {
// ...
}
});
回答by Ketan Ramani
Use this method
使用这个方法
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
回答by Latief Anwar
Yes, it has been deprecated. FusedLocationProviderClient
is easier than FusedLocationProviderApi
, because FusedLocationProviderApi
usually requires GoogleApiClient
too, which we need to connect to Google Play Service
manually. If you previously used GoogleApiClient
, now GoogleApiClient
is no longer needed (more here).
是的,它已被弃用。FusedLocationProviderClient
比 容易FusedLocationProviderApi
,因为FusedLocationProviderApi
通常也需要GoogleApiClient
,我们需要Google Play Service
手动连接。如果您以前使用过GoogleApiClient
,现在GoogleApiClient
不再需要(更多在这里)。
To get last location, can use this function:
要获取最后一个位置,可以使用此功能:
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());
}
}
});
}