Android Geofence работает после перезагрузки телефона

Я добавляю несколько геозон в одно приложение (согласно документации разрешено не более 100). Я получал обратные вызовы геозоны, а затем он остановился. 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) {

}

В логах правильно регистрируется геозона. Я реализовал IntentService в ожидании намерения. Я также пробовал широковещательный приемник, но результат был таким же. Пробовал один и тот же код с несколькими устройствами и версией ОС.


person Akshay Pure    schedule 05.12.2017    source источник
comment
вы пробовали с другим устройством Android?   -  person Aks4125    schedule 05.12.2017
comment
Да пробовал почти с 5-6 устройств   -  person Akshay Pure    schedule 05.12.2017
comment
Вы реализуете его с плавным API-интерфейсом местоположения с клиентом Google API?   -  person Aks4125    schedule 05.12.2017
comment
гугл апи клиент. developer.android.com/training/location/geofencing.html подписался на это   -  person Akshay Pure    schedule 05.12.2017
comment
предоставьте полный код для реальной проблемы. потому что данный код не является причиной вашей проблемы.   -  person Aks4125    schedule 05.12.2017
comment
добавлен полный код сейчас   -  person Akshay Pure    schedule 05.12.2017
comment
Давайте продолжим обсуждение в чате.   -  person Akshay Pure    schedule 05.12.2017
comment
@AkshayPure, как вы решили эту проблему? Я столкнулся с той же проблемой. Мне было бы полезно, если бы вы поделились подробностями. Спасибо.   -  person milan manvar    schedule 15.10.2020


Ответы (1)


Обновления местоположения через интервал отсутствуют в вашем коде.

Вы должны запросить местоположение в HIGH_ACCURACY, что позволит GPS дать вам точное местоположение в заданный интервал времени.

Согласно этому руководству, необходимо внести множество изменений. пройти выше учебник и дайте мне знать, если он не работает.

Вы должны создать запрос местоположения.

еще одно руководство

person Aks4125    schedule 05.12.2017