blob: 10773f82fa437eb56a9cab640f3d0b995519d2ff [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.location;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.TimeUtils;
import com.android.internal.util.Preconditions;
import java.util.Objects;
/**
* Represents a geographical boundary, also known as a geofence.
*
* <p>Currently only circular geofences are supported and they do not support altitude changes.
*
* @hide
*/
public final class Geofence implements Parcelable {
private final double mLatitude;
private final double mLongitude;
private final float mRadius;
private long mExpirationRealtimeMs;
/**
* Create a circular geofence (on a flat, horizontal plane).
*
* @param latitude latitude in degrees, between -90 and +90 inclusive
* @param longitude longitude in degrees, between -180 and +180 inclusive
* @param radius radius in meters
* @return a new geofence
* @throws IllegalArgumentException if any parameters are out of range
*/
public static Geofence createCircle(double latitude, double longitude, float radius,
long expirationRealtimeMs) {
return new Geofence(latitude, longitude, radius, expirationRealtimeMs);
}
Geofence(double latitude, double longitude, float radius, long expirationRealtimeMs) {
Preconditions.checkArgumentInRange(latitude, -90.0, 90.0, "latitude");
Preconditions.checkArgumentInRange(longitude, -180.0, 180.0, "latitude");
Preconditions.checkArgument(radius > 0, "invalid radius: %f", radius);
mLatitude = latitude;
mLongitude = longitude;
mRadius = radius;
mExpirationRealtimeMs = expirationRealtimeMs;
}
public double getLatitude() {
return mLatitude;
}
public double getLongitude() {
return mLongitude;
}
public float getRadius() {
return mRadius;
}
public boolean isExpired() {
return isExpired(SystemClock.elapsedRealtime());
}
/**
* Returns true if this geofence is expired with reference to the given realtime.
*/
public boolean isExpired(long referenceRealtimeMs) {
return referenceRealtimeMs >= mExpirationRealtimeMs;
}
@UnsupportedAppUsage
public static final @NonNull Parcelable.Creator<Geofence> CREATOR =
new Parcelable.Creator<Geofence>() {
@Override
public Geofence createFromParcel(Parcel in) {
return new Geofence(
in.readDouble(),
in.readDouble(),
in.readFloat(),
in.readLong());
}
@Override
public Geofence[] newArray(int size) {
return new Geofence[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeDouble(mLatitude);
parcel.writeDouble(mLongitude);
parcel.writeFloat(mRadius);
parcel.writeLong(mExpirationRealtimeMs);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Geofence)) {
return false;
}
Geofence geofence = (Geofence) o;
return Double.compare(geofence.mLatitude, mLatitude) == 0
&& Double.compare(geofence.mLongitude, mLongitude) == 0
&& Float.compare(geofence.mRadius, mRadius) == 0
&& mExpirationRealtimeMs == geofence.mExpirationRealtimeMs;
}
@Override
public int hashCode() {
return Objects.hash(mLatitude, mLongitude, mRadius);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Geofence[(").append(mLatitude).append(", ").append(mLongitude).append(")");
builder.append(" ").append(mRadius).append("m");
if (mExpirationRealtimeMs < Long.MAX_VALUE) {
if (isExpired()) {
builder.append(" expired");
} else {
builder.append(" expires=");
TimeUtils.formatDuration(mExpirationRealtimeMs, builder);
}
}
builder.append("]");
return builder.toString();
}
}