なぜ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()
の内側にFusedLocationProviderClient
インスタンスを作成する
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
そして、あなたがしなければならないのは、電話をかけることだけです
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(this, 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
}
}
});
単純じゃないですか?
昨日、Googleは公式開発者ページを という警告 で更新しました。
FusedLocationProviderApiクラスを引き続き使用し、Google Playサービスバージョン12.0.0が入手可能になるまでFusedLocationProviderClientクラスに移行しないでください。これは2018年初頭に出荷される予定です。バージョン12.0.0より前のFusedLocationProviderClientを使用するとGoogle Playサービスが端末上で更新されます。ご不便をおかけして申し訳ありません。
だからGoogleが問題を解決するまで私たちは廃止予定のLocationServices.FusedLocationApi
を使い続けるべきだと思う。
警告は表示されなくなりました。Google Playサービス11.6 2017年11月6日、リリースノート のコメント: Play Servicesは、バックグラウンドで自動的に更新されてもクラッシュしません。それで、私たちは今新しいFusedLocationProviderClient
を使うことができます。
// 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>
この方法を使う
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
はい、廃止予定です。
以下はnew FusedLocationProviderClient を使用する際に必要となるポイントです。
com.google.Android.gms.location.FusedLocationProviderClient;
????としてインポートするimport com.google.Android.gms.location.LocationCallback;
としてインポートimport com.google.Android.gms.location.LocationResult;
としてインポート正気のために私は11.2.0にこだわっています。私は廃止予定を理解していません。 2017年11月3日現在、Googleのドキュメントではこれまでのところ参照しています:LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mListener);