2016-07-07 56 views
2

我試圖在我的應用程序中實現geofencing,所以無論何時用戶輸入一個geofence對象時,都會發生。繼Android開發者指南(使您的應用程序位置感知),當我加入這個片段:Geofencing:GoogleApiClient尚未連接

LocationServices.GeofencingApi.addGeofences(
      mGoogleApiClient, 
      getGeofencingRequest(), 
      getGeofencePendingIntent() 
    ).setResultCallback(this); 

我把這個在我的onMapReady()加載後我的地理圍欄,讓他們將立即被添加到我的應用程序。不過,我得到這個錯誤:我相信我已經建立了我的onCreate()的谷歌API客戶端,但我仍然得到這個錯誤。如果我刪除上面的代碼片段(第一段代碼片段),那麼錯誤不再存在。我究竟做錯了什麼?

代碼:

公共類MapsActivity擴展AppCompatActivity實現OnMapReadyCallback,ConnectionCallbacks,OnConnectionFailedListener,LocationListener的,ResultCallback {

//Google Maps 
public GoogleMap mMap; 
private GoogleApiClient mGoogleApiClient; 
LocationRequest mLocationRequest = new LocationRequest(); 
public Location mCurrentLocation; 
private static final int FINE_LOCATION_PERMISSION_REQUEST = 1; 
private static final int CONNECTION_RESOLUTION_REQUEST = 2; 
List<Marker> markerList = new ArrayList<Marker>(); 

//Temporary Vars 
double lat = 0; 
double lon = 0; 
Marker current_marker; 

//Request Info vars 
static final int GET_DETAILS = 1; 
static final int EDIT_DETAILS = 2; 


//Debug 
private static final String TAG = "GeekysMessage"; 

SharedPreferences sharedPreferences; 
int markerCount; 

private Toolbar toolbar; 


//Geofence 
private boolean mGeofencesAdded; 
ArrayList mGeofenceList = new ArrayList<Geofence>(); 
private PendingIntent mGeofencePendingIntent; 
public int geofenceCount; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_maps); 
    toolbar = (Toolbar) findViewById(R.id.my_toolbar); 
    setSupportActionBar(toolbar); 


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

    buildGoogleAPIClient(); 
    //Geofence 
    // Empty list for storing geofences. 
    mGeofenceList = new ArrayList<Geofence>(); 

    // Initially set the PendingIntent used in addGeofences() and removeGeofences() to null. 
    mGeofencePendingIntent = null; 
} 

@Override 
protected void onResume() { 
    super.onResume(); 

    buildGoogleAPIClient(); 

    if (mGoogleApiClient.isConnected()) { 
     startLocationUpdates(); 
    } 
} 

//LOCATION 
private void buildGoogleAPIClient() { 
    if (mGoogleApiClient == null) { 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
     createLocationRequest(); 
    } 
} 

protected void createLocationRequest() { 
    mLocationRequest = new LocationRequest(); 
    mLocationRequest.setInterval(10000); 
    mLocationRequest.setFastestInterval(5000); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
} 

protected void onStart() { 
    mGoogleApiClient.connect(); 
    super.onStart(); 
} 

protected void onStop() { 
    mGoogleApiClient.disconnect(); 
    super.onStop(); 
} 



protected void startLocationUpdates() { 
     LocationServices.FusedLocationApi.requestLocationUpdates(
       mGoogleApiClient, mLocationRequest, this); 
} 

@Override 
public void onConnected(@Nullable Bundle bundle) { 
    if (ContextCompat.checkSelfPermission(this, 
      Manifest.permission.ACCESS_FINE_LOCATION) 
      == PackageManager.PERMISSION_GRANTED) { 
     if (mCurrentLocation == null) { 
      mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
      updateUI(); 
     } 
     startLocationUpdates(); 

    } 

} 

@TargetApi(Build.VERSION_CODES.N) 
@Override 
public void onLocationChanged(Location location) { 
    mCurrentLocation = location; 
    updateUI(); 
    Toast.makeText(this, "Updated", 
      Toast.LENGTH_SHORT).show(); 
} 

private void updateUI() { 

} 

@Override 
public void onConnectionSuspended(int i) { 
    Toast.makeText(this, "Connection suspended", Toast.LENGTH_SHORT).show(); 
} 

@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
    if (connectionResult.hasResolution()) { 
     try { 
      connectionResult.startResolutionForResult(this, CONNECTION_RESOLUTION_REQUEST); 
     } catch (IntentSender.SendIntentException e) { 
      // There was an error with the resolution intent. Try again. 
      mGoogleApiClient.connect(); 
     } 
    } else { 
     Dialog dialog = GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 1); 
     dialog.show(); 
    } 
} 

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

@Override 
protected void onPause() { 
    super.onPause(); 
    // Stop location updates to save battery, but don't disconnect the GoogleApiClient object. 
    if (mGoogleApiClient.isConnected()) { 
     stopLocationUpdates(); 
    } 
} 


int requestCode = 0; 

//MAP 
@Override 
public void onMapReady(GoogleMap googleMap) { 
    mMap = googleMap; 

    //load all saved markers 
    loadMarkers(); 

    LocationServices.GeofencingApi.addGeofences(
      mGoogleApiClient, 
      getGeofencingRequest(), 
      getGeofencePendingIntent() 
    ).setResultCallback(this); 

    //Permissions 
    if (ContextCompat.checkSelfPermission(this, 
      Manifest.permission.ACCESS_FINE_LOCATION) 
      != PackageManager.PERMISSION_GRANTED) { 
     ActivityCompat.requestPermissions(this, 
       new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
       FINE_LOCATION_PERMISSION_REQUEST); 
    } else { 
     mMap.setMyLocationEnabled(true); 

    } 


} 
private void loadMarkers() { 

    // Opening the sharedPreferences object 
    sharedPreferences = getSharedPreferences("location", 0); 

    // Getting number of locations already stored 
    markerCount = sharedPreferences.getInt("markerCount", 0); 

    //if marker are already saved 
    if (markerCount != 0) { 

     String lat = ""; 
     String lng = ""; 
     String marker_title = null; 
     String marker_snippet = null; 
     int marker_radius = 0; 

     for (int i=0; i < markerCount; i++) { 
      lat = sharedPreferences.getString("lat"+i, "0"); 
      lng = sharedPreferences.getString("lng"+i, "0"); 
      marker_title = sharedPreferences.getString("title"+i, ""); 
      marker_snippet = sharedPreferences.getString("snippet"+i, ""); 
      marker_radius = sharedPreferences.getInt("radius"+i, 20); 

      double lati = Double.valueOf(lat); 
      double lngi = Double.valueOf(lng); 

      addMarker(lati, lngi, marker_title, marker_snippet); 
      addGeofence(marker_title, lati, lngi, marker_radius); 

     } 

    } 
} 
private PendingIntent getGeofencePendingIntent() { 
    // Reuse the PendingIntent if we already have it. 
    if (mGeofencePendingIntent != null) { 
     return mGeofencePendingIntent; 
    } 
    Intent intent = new Intent(this, GeofenceTransitionsIntentService.class); 
    // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when 
    // calling addGeofences() and removeGeofences(). 
    return PendingIntent.getService(this, 0, intent, PendingIntent. 
      FLAG_UPDATE_CURRENT); 
} 

public void addMarker(double lati, double longi, String title, String snippet){ 
    if (snippet==""){snippet = null;} 
    Marker m = mMap.addMarker(new MarkerOptions() 
      .position(new LatLng(lati, longi)) 
      .title(title) 
      .snippet(snippet) 
      .draggable(true)); 
    markerList.add(m); 
} 

public void saveMarkers(){ 
    SharedPreferences.Editor editor = sharedPreferences.edit(); 
    editor.clear(); 
    markerCount = 0; 
    for (Marker i : markerList) { 
     //Save to sharedprefences 
     markerCount++; 

     editor.putString("lat" + Integer.toString((markerCount - 1)), String.valueOf(i.getPosition().latitude)); 
     editor.putString("lng" + Integer.toString((markerCount - 1)), String.valueOf(i.getPosition().longitude)); 
     editor.putString("title" + Integer.toString((markerCount - 1)),i.getTitle()); 
     editor.putString("snippet" + Integer.toString((markerCount - 1)),i.getSnippet()); 
     editor.putInt("markerCount", markerCount); 

     editor.commit(); 
    } 
} 

private GeofencingRequest getGeofencingRequest() { 
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER); 
    builder.addGeofences(mGeofenceList); 
    return builder.build(); 
} 

public void addGeofence(String key, double lat, double lng, int radius){ 
    mGeofenceList.add(new Geofence.Builder() 
      // Set the request ID of the geofence. This is a string to identify this 
      // geofence. 
      .setRequestId(key) 

      .setCircularRegion(
        lat, 
        lng, 
        radius 
      ) 
      .setExpirationDuration(12*60*60*1000) 
      .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | 
        Geofence.GEOFENCE_TRANSITION_EXIT) 
      .build()); 

    Circle circle = mMap.addCircle(new CircleOptions() 
      .center(new LatLng(lat, lng)) 
      .radius(radius) 
      .fillColor(Color.parseColor("#02bbff"))); 



} 

@Override 
public void onResult(@NonNull Status status) { 
    if (status.isSuccess()) { 
     // Update state and save in shared preferences. 
     mGeofencesAdded = !mGeofencesAdded; 
     Toast.makeText(
       this, 
       getString(mGeofencesAdded ? R.string.geofences_added : 
         R.string.geofences_removed), 
       Toast.LENGTH_SHORT 
     ).show(); 
    } else { 
     // Get the status code for the error and log it using a user-friendly message. 
     String errorMessage = GeofenceErrorMessages.getErrorString(this, 
       status.getStatusCode()); 
     Log.e(TAG, errorMessage); 
    } 
} 
} 

任何幫助將不勝感激。

回答

1

您在撥打onStop()致電mGoogleApiClient.disconnect();LocationServices.GeofencingApi.addGeofences(代碼必須觸發onStop,所以mGoogleApiClient會斷開連接。

中的onCreate在OnMapReady

Boolean fromOnMapReady = false; 

在調用OnStop

@Override 
public void onMapReady(GoogleMap googleMap) { 
    fromOnMapReady = true; 

protected void onStop() { 
    if(!fromOnMapReady){ 
    mGoogleApiClient.disconnect(); 
    } 
    super.onStop(); 
} 

一旦任何進程運行完畢後重新fromOnMapReady = false否則mGoogleApiClient不會斷開需要

+0

沒有工作...我甚至刪除了該事件,仍然無法連接到谷歌的API ...任何其他建議? –

+0

它連接一次嗎? – suku

+0

不要擔心我修好了,生病給你信貸雖然:) –

相關問題