我正在为一个应用程序添加多个地理围栏。(根据文档允许最多100个。)我收到了地理围栏的回调然后停止了。 只有当我重新启动手机时,地理围栏才能顺利运行。几分钟后它再次停止工作。
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) {
}
在日志中,地理围栏正在正确注册。 我已在待处理的意图中实现了IntentService。我也试过广播接收器,但结果是一样的。 尝试使用多个设备和操作系统版本的相同代码。
答案 0 :(得分:0)
代码中缺少间隔位置更新。
您必须在HIGH_ACCURACY
请求位置,以便GPS能够在给定的间隔时间为您提供准确的位置。
根据this tutorial,需要进行大量更改。 浏览上面的教程,如果它不起作用,请告诉我。
您必须创建位置请求。