我正在开发一个名为Galileo的新开源库,它可以帮助开发人员在一行中使用Google的location api。 但是,当我恢复我的应用程序时,在OnConnected中,我得到了客户端尚未连接的异常。问题是,使用他们的方法,一切正常,但我无法工作我的实现。这是我到目前为止所得到的:
Galileo.java:
public class Galileo {
static volatile Galileo singleton;
private GoogleApiClient mGoogleApiClient;
private LocationManager locationManager;
private LocationListener locationListener;
Galileo (GoogleApiClient mGoogleApiClient, LocationListener locationListener){
this.mGoogleApiClient = mGoogleApiClient;
this.locationListener = locationListener;
}
public static Galileo with(@NonNull GoogleApiClient mGoogleApiClient, @NonNull LocationListener locationListener ) {
if (mGoogleApiClient == null || locationListener==null) {
throw new IllegalArgumentException("context == null");
}
if (singleton == null) {
synchronized (Galileo.class) {
if (singleton == null) {
singleton = new Builder(mGoogleApiClient, locationListener).build();
}
}
}
return singleton;
}
public LocationRequest load(){
return new LocationRequest(this);
}
LocationListener getLocationListener(){
return this.locationListener;
}
GoogleApiClient getmGoogleApiClient(){
return this.mGoogleApiClient;
}
public static class Builder {
private final GoogleApiClient mGoogleApiClient;
private final LocationListener locationListener;
public Builder(@NonNull GoogleApiClient mGoogleApiClient, @NonNull LocationListener locationListener) {
if (mGoogleApiClient == null || locationListener == null) {
throw new IllegalArgumentException("Context must not be null.");
}
this.mGoogleApiClient = mGoogleApiClient;
this.locationListener = locationListener;
}
/**
* Toggle whether debug logging is enabled.
* <p>
* <b>WARNING:</b> Enabling this will result in excessive object allocation. This should be only
* be used for debugging purposes. Do NOT pass {@code BuildConfig.DEBUG}.
*/
public Galileo build() {
GoogleApiClient mGoogleApiClient = this.mGoogleApiClient;
LocationListener locationListener = this.locationListener;
return new Galileo(mGoogleApiClient, locationListener);
}
}
}
LocationRequest.java:
public class LocationRequest {
private LocationListener locationListener;
private GoogleApiClient mGoogleApiClient;
private float mDistance;
private int mTime;
private int priority;
private boolean askForGPS;
private com.google.android.gms.location.LocationRequest mLocationRequest;
LocationRequest(Galileo galileo) {
this.mGoogleApiClient = galileo.getmGoogleApiClient();
this.locationListener = galileo.getLocationListener();
this.mTime = 10000;
this.priority = com.google.android.gms.location.LocationRequest.PRIORITY_HIGH_ACCURACY;
this.askForGPS = false;
}
public LocationRequest time(int mTime){
this.mTime = mTime;
return this;
}
public LocationRequest distance(float mDistance){
this.mDistance = mDistance;
return this;
}
public void go(){
createLocationRequest();
startLocationUpdates();
}
public void stop(){
stopLocationUpdates();
}
protected void stopLocationUpdates() {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
// The final argument to {@code requestLocationUpdates()} is a LocationListener
// (http://developer.android.com/reference/com/google/android/gms/location/LocationListener.html).
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationListener);
}
protected void startLocationUpdates() {
// The final argument to {@code requestLocationUpdates()} is a LocationListener
// (http://developer.android.com/reference/com/google/android/gms/location/LocationListener.html).
System.out.print(mGoogleApiClient.isConnected());
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest , locationListener);
}
protected void createLocationRequest() {
mLocationRequest = new com.google.android.gms.location.LocationRequest();
// Sets the desired interval for active location updates. This interval is
// inexact. You may not receive updates at all if no location sources are available, or
// you may receive them slower than requested. You may also receive updates faster than
// requested if other applications are requesting location at a faster interval.
mLocationRequest.setInterval(mTime);
// Sets the fastest rate for active location updates. This interval is exact, and your
// application will never receive updates faster than this value.
mLocationRequest.setFastestInterval(mTime/2);
mLocationRequest.setPriority(priority);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(@NonNull LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
/*try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
//status.startResolutionForResult(MapsActivity.this, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}*/
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
}
和MapsActivity.java:
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
//createLocationRequest();
}
protected void stopLocationUpdates() {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
// The final argument to {@code requestLocationUpdates()} is a LocationListener
// (http://developer.android.com/reference/com/google/android/gms/location/LocationListener.html).
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
protected void startLocationUpdates() {
// The final argument to {@code requestLocationUpdates()} is a LocationListener
// (http://developer.android.com/reference/com/google/android/gms/location/LocationListener.html).
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
// Sets the desired interval for active location updates. This interval is
// inexact. You may not receive updates at all if no location sources are available, or
// you may receive them slower than requested. You may also receive updates faster than
// requested if other applications are requesting location at a faster interval.
mLocationRequest.setInterval(10000);
// Sets the fastest rate for active location updates. This interval is exact, and your
// application will never receive updates faster than this value.
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(@NonNull LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
MapsActivity.this, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(48.162253, 17.0463122), 15));
MarkerOptions marker = new MarkerOptions().position(new LatLng(48.162253, 17.0463122)).title("Hello Maps ");
mMap.addMarker(marker);
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
behavior.setState(BottomSheetBehaviorGoogleMapsLike.STATE_COLLAPSED);
String imageURL = "https://maps.googleapis.com/maps/api/streetview?size=400x400&location="+String.valueOf(marker.getPosition().latitude)+","+String.valueOf(marker.getPosition().longitude);
Picasso.with(MapsActivity.this).load(imageURL).into(imageView);
bottomSheetTextView.setText(marker.getTitle());
currentMarker = marker;
Geocoder geocoder;
List<Address> addresses;
String address;
geocoder = new Geocoder(MapsActivity.this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(marker.getPosition().latitude, marker.getPosition().longitude, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
address = addresses.get(0).getAddressLine(0);
} catch (IOException e) {
address = "";
e.printStackTrace();
}
addressView.setText(address);
return false;
}
});
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
if (behavior.getState() == BottomSheetBehaviorGoogleMapsLike.STATE_COLLAPSED) {
behavior.setState(BottomSheetBehaviorGoogleMapsLike.STATE_HIDDEN);
}
currentMarker = null;
}
});
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
MarkerOptions marker = new MarkerOptions().position(latLng).title("Hello Maps ");
mMap.addMarker(marker);
}
});
}
@Override
protected void onStart() {
super.onStart();
String[] LOCATION_PERMISSIONS = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
Permission.PermissionBuilder permissionBuilder =
new Permission.PermissionBuilder(LOCATION_PERMISSIONS, 1000, new Permission.PermissionCallback() {
@Override
public void onPermissionGranted(int i) {
buildGoogleApiClient();
mGoogleApiClient.connect();
}
@Override
public void onPermissionDenied(int i) {
}
@Override
public void onPermissionAccessRemoved(int i) {
}
});
requestAppPermissions(permissionBuilder.build());
}
@Override
public void onResume() {
super.onResume();
// Within {@code onPause()}, we pause location updates, but leave the
// connection to GoogleApiClient intact. Here, we resume receiving
// location updates if the user has requested them.
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
Galileo.with(mGoogleApiClient,this).load().go();
}
}
@Override
protected void onPause() {
super.onPause();
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
Galileo.with(mGoogleApiClient,this).load().stop();
}
}
@Override
protected void onStop() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onStop();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation!=null){
Log.d("Lat, lon", String.valueOf(mLastLocation.getLatitude()) + " ," + String.valueOf(mLastLocation.getLongitude()));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()), 15));
}
//Log.d(TAG, String.valueOf(mGoogleApiClient.isConnected()));
if(mGoogleApiClient.isConnected()){
Galileo.with(mGoogleApiClient,this).load().go();}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
@Override
public void onLocationChanged(Location location) {
if(mLastLocation==null){
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15));
}
mLastLocation = location;
Log.d("Lat, lon", String.valueOf(mLastLocation.getLatitude()) + " ," + String.valueOf(mLastLocation.getLongitude()));
//mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()), 15));
}