2017-12-05 17 views
0

1つのアプリケーションに複数のジオフェンスを追加しています(ドキュメントに応じて最大100個まで許されています)。私はジオフェンスのコールバックを取得していました。 ジオフェンスは、電話機を再起動したときにだけスムーズに動作します。数分後に再び動作を停止します。Android Geofenceは電話の再起動後に動作します

public class GeoFenceHelper implements IGeoFenceListener, GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener { 

private Context context; 
private GeofencingClient mGeoFencingClient; 
private PendingIntent geoFencePendingIntent; 
private String TAG = GeoFenceHelper.class.getSimpleName(); 
private GoogleApiClient mGoogleApiClient; 
private Location mLastLocation; 
Location tempLocation = new Location(""); 
/** 
* The list of geoFences used in this sample. 
*/ 
private ArrayList<Geofence> mGeoFenceList; 
private List<GeoFenceModel> geoFenceEntries; 
private ArrayList<String> removeGeoFenceList = new ArrayList<>(); 

public GeoFenceHelper(Context context) { 
    this.context = context; 
    mGeoFenceList = new ArrayList<>(); 
    mGeoFencingClient = LocationServices.getGeofencingClient(context); 
} 

public void registerGeoFence(List<GeoFenceModel> geoFenceEntries) { 

    mGeoFenceList.clear(); 
    this.geoFenceEntries = geoFenceEntries; 

     if (DatabaseManager.getInstance(context).getGeoFenceLocationCount() <= Constants.MAX_GEOFENCE_ENTRY_COUNT) { 
      addGeoFences(geoFenceEntries); 
     } else { 
      buildGoogleApiClient(); 
     } 
} 

private void addGeoFences(List<GeoFenceModel> geoFenceEntries) { 
    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     return; 
    } 

    for (GeoFenceModel geoFenceEntry : geoFenceEntries) { 

     if(geoFenceEntry.getId()==Constants.DESTINATION_REACHED_ID) { 
      removeGeoFenceList.clear(); 
      removeGeoFenceList.add(""+geoFenceEntry.getId()); 
      unregisterGeoFence(removeGeoFenceList); 
     } 
      Geofence geoFence = new Geofence.Builder() 
        .setRequestId(String.valueOf(geoFenceEntry.getId())) 
        .setExpirationDuration(geoFenceEntry.getExpireDuration()) 
        .setCircularRegion(
          geoFenceEntry.getLatitude(), 
          geoFenceEntry.getLongitude(), 
          geoFenceEntry.getRadius() 
        ) 
        .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) 
        .build(); 

      CustomLogger.logE("GEOGENCE", "Geo Fence lat = " + geoFenceEntry.getLatitude() + " log = " + geoFenceEntry.getLongitude() + "Radius = " + geoFenceEntry.getRadius()+" Expiry "+geoFenceEntry.getExpireDate()); 
      mGeoFenceList.add(geoFence); 
    } 

    mGeoFencingClient.addGeofences(getGeoFencingRequest(mGeoFenceList), getGeoFencePendingIntent()); 
    Utils.stopLocationUpdate(context); 
} 

@Override 
public void unregisterGeoFence(List<String> genFenceList) { 
    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     return; 
    } 
    CustomLogger.logE("GeoFence","Remove GeoFence "+genFenceList.get(0)); 
    mGeoFencingClient.removeGeofences(genFenceList); 
} 

/** 
* Builds and returns a GeoFencingRequest. Specifies the list of geoFences to be monitored. 
* Also specifies how the geoFence notifications are initially triggered. 
* 
* @param mGeoFenceList 
*/ 
private GeofencingRequest getGeoFencingRequest(ArrayList<Geofence> mGeoFenceList) { 
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER); 
    builder.addGeofences(mGeoFenceList); 
    return builder.build(); 
} 

private PendingIntent getGeoFencePendingIntent() { 
    // Reuse the PendingIntent if we already have it. 
    if (geoFencePendingIntent != null) { 
     return geoFencePendingIntent; 
    } 
    Intent intent = new Intent(context, GeofenceTransitionsIntentService.class); 
    geoFencePendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    return geoFencePendingIntent; 
} 

//Location related code 
private synchronized void buildGoogleApiClient() { 
    mGoogleApiClient = new GoogleApiClient.Builder(this.context) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API).build(); 

    if (mGoogleApiClient != null && !mGoogleApiClient.isConnected()) { 
     mGoogleApiClient.connect(); 
    } 
} 

@Override 
public void onConnected(@Nullable Bundle bundle) { 
    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED 
      && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 

     return; 
    } 
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 

    if (mLastLocation != null) { 
     double latitude = mLastLocation.getLatitude(); 
     double longitude = mLastLocation.getLongitude(); 
     CustomLogger.logE("tempLocation", "lat " + latitude + "long " + longitude); 

     List<GeoFenceModel> geoFenceLocations = DatabaseManager.getInstance(context).getGeoFenceLocation(); 
     calculateLocationDistance(mLastLocation, geoFenceLocations); 
     try { 
      deleteLocations(geoFenceLocations); 
      addGeoFences(geoFenceEntries); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } else { 
     CustomLogger.logE("tempLocation", "(Couldn't get the tempLocation. Make sure tempLocation is enabled on the device)"); 
    } 
} 

private void deleteLocations(List<GeoFenceModel> geoFenceLocations) throws SQLException { 
    int reduceCount = Math.abs(Constants.MAX_GEOFENCE_ENTRY_COUNT - geoFenceLocations.size()); 

    CustomLogger.logE("GEOGENCE", "Geo Fence App lat = "+geoFenceLocations.get(0).getLatitude() + " log = "+ geoFenceLocations.get(0).getLongitude() + "App sepcific = "+ geoFenceLocations.get(0).isAppSpecific()); 
    GeoFenceModel geoFenceModel = null; 
    for (int i = 0; i < reduceCount; i++) { 

     if(geoFenceLocations.get(0).isAppSpecific()) 
     { 
      geoFenceModel = geoFenceLocations.remove(1); //because app specific item will be available at top of the list 
     } 
     else 
     { 
      geoFenceModel = geoFenceLocations.remove(0); 
     } 
     DatabaseManager.getInstance(context).getHelper().getNotificationGeoFenceModelDao().delete(geoFenceModel); 
     try { 
      List notificationIds = new ArrayList<String>(); 
      notificationIds.add(String.valueOf(geoFenceModel.getId())); 
      unregisterGeoFence(notificationIds); 
     } 
     catch (Exception e) 
     { 
      CustomLogger.logE("GEOFENCE ","EXCEPTION"+e); 
     } 

     for (GeoFenceModel geoFence: geoFenceEntries) { 
      if (geoFence.getId()==geoFenceModel.getId()) 
      { 
       geoFenceEntries.remove(geoFenceModel); 
       CustomLogger.logE("GEOGENCE", "Geo Fence Removed lat = "+geoFence.getLatitude() + " log = "+ geoFence.getLongitude() + "Radius = "+ geoFence.getRadius()); 
      } 
     } 
    } 
} 


private void calculateLocationDistance(Location mLastLocation, List<GeoFenceModel> geoFenceLocations) { 

    for (GeoFenceModel geoFenceLocation : geoFenceLocations) { 
     tempLocation.setLatitude(geoFenceLocation.getLatitude()); 
     tempLocation.setLongitude(geoFenceLocation.getLongitude()); 
     geoFenceLocation.setDistanceInMeters(mLastLocation.distanceTo(tempLocation)); 
    } 
    Collections.sort(geoFenceLocations); 
} 

@Override 
public void onConnectionSuspended(int i) { 

} 

@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 

} 

ログには、geofenceが正しく登録されています。 保留中のインテントでIntentServiceを実装しました。放送受信機も試しましたが、結果は同じでした。 複数のデバイスとOSバージョンで同じコードを試しました。

+0

ますが、別のAndroidデバイスで試してみましたか? – Aks4125

+0

はい、ほとんど5-6デバイスで試しました –

+0

Google apiクライアントと融合した場所APIで実装していますか? – Aks4125

答えて

0

コードに間隔の場所の更新がありません。

HIGH_ACCURACYに位置をリクエストする必要があります。これにより、GPSは所定の間隔で正確な位置情報を提供します。

this tutorialごとに多くの変更が必要です。 上記のチュートリアルを完了し、問題が解決しない場合は教えてください。

ロケーションリクエストを作成する必要があります。

one more tutorial

関連する問題